From f5b2cd891a5ed4bbddd0084cd52244b605c0b497 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 23 Mar 2015 18:45:30 +0000 Subject: [PATCH] R600/SI: Allow commuting compares This enables very common cases to switch to the smaller encoding. All of the standard LLVM canonicalizations of comparisons are the opposite of what we want. Compares with constants are moved to the RHS, but the first operand can be an inline immediate, literal constant, or SGPR using the 32-bit VOPC encoding. There are additional bad canonicalizations that should also be fixed, such as canonicalizing ge x, k to gt x, (k + 1) if this makes k no longer an inline immediate value. llvm-svn: 232988 --- llvm/lib/Target/R600/SIInstrInfo.cpp | 26 +- llvm/lib/Target/R600/SIInstrInfo.h | 6 +- llvm/lib/Target/R600/SIInstrInfo.td | 98 ++- llvm/lib/Target/R600/SIInstructions.td | 138 ++-- llvm/test/CodeGen/R600/commute-compares.ll | 697 ++++++++++++++++++ llvm/test/CodeGen/R600/fceil64.ll | 8 +- llvm/test/CodeGen/R600/ffloor.f64.ll | 8 +- llvm/test/CodeGen/R600/ftrunc.f64.ll | 4 +- llvm/test/CodeGen/R600/i1-copy-phi.ll | 2 +- .../test/CodeGen/R600/llvm.AMDGPU.div_fmas.ll | 18 +- llvm/test/CodeGen/R600/llvm.round.f64.ll | 2 +- llvm/test/CodeGen/R600/llvm.round.ll | 2 +- llvm/test/CodeGen/R600/or.ll | 2 +- llvm/test/CodeGen/R600/setcc-opt.ll | 18 +- llvm/test/CodeGen/R600/sgpr-control-flow.ll | 6 +- llvm/test/CodeGen/R600/trunc-cmp-constant.ll | 14 +- llvm/test/CodeGen/R600/trunc.ll | 8 +- llvm/test/CodeGen/R600/valu-i1.ll | 16 +- llvm/test/CodeGen/R600/xor.ll | 4 +- 19 files changed, 921 insertions(+), 156 deletions(-) create mode 100644 llvm/test/CodeGen/R600/commute-compares.ll diff --git a/llvm/lib/Target/R600/SIInstrInfo.cpp b/llvm/lib/Target/R600/SIInstrInfo.cpp index c8468f985247..b0952e357f1f 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.cpp +++ b/llvm/lib/Target/R600/SIInstrInfo.cpp @@ -426,7 +426,29 @@ SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB, } } -unsigned SIInstrInfo::commuteOpcode(unsigned Opcode) const { +static unsigned commuteCompareOpcode(unsigned Opcode) { + // Compares have arbitrarily selected that < is the "original" and > is the + // "reverse" + + int NewOpc; + + NewOpc = AMDGPU::getCommuteCmpRev(Opcode); + if (NewOpc != -1) + return NewOpc; + + NewOpc = AMDGPU::getCommuteCmpOrig(Opcode); + if (NewOpc != -1) + return NewOpc; + + return Opcode; +} + +unsigned SIInstrInfo::commuteOpcode(const MachineInstr &MI) const { + const unsigned Opcode = MI.getOpcode(); + + if (MI.isCompare()) + return commuteCompareOpcode(Opcode); + int NewOpc; // Try to map original to commuted opcode @@ -797,7 +819,7 @@ MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI, } if (MI) - MI->setDesc(get(commuteOpcode(MI->getOpcode()))); + MI->setDesc(get(commuteOpcode(*MI))); return MI; } diff --git a/llvm/lib/Target/R600/SIInstrInfo.h b/llvm/lib/Target/R600/SIInstrInfo.h index 3a0d63b9098f..62140086bb61 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.h +++ b/llvm/lib/Target/R600/SIInstrInfo.h @@ -114,7 +114,7 @@ public: // register. If there is no hardware instruction that can store to \p // DstRC, then AMDGPU::COPY is returned. unsigned getMovOpcode(const TargetRegisterClass *DstRC) const; - unsigned commuteOpcode(unsigned Opcode) const; + unsigned commuteOpcode(const MachineInstr &MI) const; MachineInstr *commuteInstruction(MachineInstr *MI, bool NewMI = false) const override; @@ -349,6 +349,10 @@ namespace AMDGPU { int getVOPe32(uint16_t Opcode); int getCommuteRev(uint16_t Opcode); int getCommuteOrig(uint16_t Opcode); + + int getCommuteCmpRev(uint16_t Opcode); + int getCommuteCmpOrig(uint16_t Opcode); + int getAddr64Inst(uint16_t Opcode); int getAtomicRetOp(uint16_t Opcode); int getAtomicNoRetOp(uint16_t Opcode); diff --git a/llvm/lib/Target/R600/SIInstrInfo.td b/llvm/lib/Target/R600/SIInstrInfo.td index 910ee075c304..583fa5f77935 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.td +++ b/llvm/lib/Target/R600/SIInstrInfo.td @@ -829,6 +829,11 @@ class VOP2_REV { bit IsOrig = isOrig; } +class VOPC_REV { + string RevOp = revOp; + bit IsOrig = isOrig; +} + class AtomicNoRet { string NoRetOp = noRetOp; bit IsRet = isRet; @@ -1069,9 +1074,10 @@ multiclass VOP3b_3_m pattern, string opName, - bit HasMods, bit defExec> { + bit HasMods, bit defExec, string revOp> { - def "" : VOP3_Pseudo ; + def "" : VOP3_Pseudo , + VOPC_REV; def _si : VOP3_Real_si , VOP3DisableFields<1, 0, HasMods> { @@ -1257,7 +1263,7 @@ class VOPC_Pseudo pattern, string opName> : } multiclass VOPC_m pattern, - string opName, bit DefExec> { + string opName, bit DefExec, string revOpName = ""> { def "" : VOPC_Pseudo ; def _si : VOPC, @@ -1274,11 +1280,11 @@ multiclass VOPC_m pattern, multiclass VOPC_Helper pat32, dag out64, dag ins64, string asm64, list pat64, - bit HasMods, bit DefExec> { + bit HasMods, bit DefExec, string revOp> { defm _e32 : VOPC_m ; defm _e64 : VOP3_C_m ; + opName, HasMods, DefExec, revOp>; } // Special case for class instructions which only have modifiers on @@ -1286,16 +1292,17 @@ multiclass VOPC_Helper pat32, dag out64, dag ins64, string asm64, list pat64, - bit HasMods, bit DefExec> { + bit HasMods, bit DefExec, string revOp> { defm _e32 : VOPC_m ; defm _e64 : VOP3_C_m , + opName, HasMods, DefExec, revOp>, VOP3DisableModFields<1, 0, 0>; } multiclass VOPCInst : VOPC_Helper < op, opName, P.Ins32, P.Asm32, [], @@ -1307,7 +1314,7 @@ multiclass VOPCInst ; multiclass VOPCClassInst ; -multiclass VOPC_F32 : - VOPCInst ; +multiclass VOPC_F32 : + VOPCInst ; -multiclass VOPC_F64 : - VOPCInst ; +multiclass VOPC_F64 : + VOPCInst ; -multiclass VOPC_I32 : - VOPCInst ; +multiclass VOPC_I32 : + VOPCInst ; -multiclass VOPC_I64 : - VOPCInst ; +multiclass VOPC_I64 : + VOPCInst ; multiclass VOPCX - : VOPCInst ; + PatLeaf cond = COND_NULL, + string revOp = ""> + : VOPCInst ; -multiclass VOPCX_F32 : - VOPCX ; +multiclass VOPCX_F32 : + VOPCX ; -multiclass VOPCX_F64 : - VOPCX ; +multiclass VOPCX_F64 : + VOPCX ; -multiclass VOPCX_I32 : - VOPCX ; +multiclass VOPCX_I32 : + VOPCX ; -multiclass VOPCX_I64 : - VOPCX ; +multiclass VOPCX_I64 : + VOPCX ; multiclass VOP3_Helper pat, int NumSrcArgs, bit HasMods> : VOP3_m < @@ -2209,15 +2217,6 @@ def getVOPe32 : InstrMapping { let ValueCols = [["4"]]; } -// Maps an original opcode to its commuted version -def getCommuteRev : InstrMapping { - let FilterClass = "VOP2_REV"; - let RowFields = ["RevOp"]; - let ColFields = ["IsOrig"]; - let KeyCol = ["1"]; - let ValueCols = [["0"]]; -} - def getMaskedMIMGOp : InstrMapping { let FilterClass = "MIMG_Mask"; let RowFields = ["Op"]; @@ -2235,6 +2234,33 @@ def getCommuteOrig : InstrMapping { let ValueCols = [["1"]]; } +// Maps an original opcode to its commuted version +def getCommuteRev : InstrMapping { + let FilterClass = "VOP2_REV"; + let RowFields = ["RevOp"]; + let ColFields = ["IsOrig"]; + let KeyCol = ["1"]; + let ValueCols = [["0"]]; +} + +def getCommuteCmpOrig : InstrMapping { + let FilterClass = "VOPC_REV"; + let RowFields = ["RevOp"]; + let ColFields = ["IsOrig"]; + let KeyCol = ["0"]; + let ValueCols = [["1"]]; +} + +// Maps an original opcode to its commuted version +def getCommuteCmpRev : InstrMapping { + let FilterClass = "VOPC_REV"; + let RowFields = ["RevOp"]; + let ColFields = ["IsOrig"]; + let KeyCol = ["1"]; + let ValueCols = [["0"]]; +} + + def getMCOpcodeGen : InstrMapping { let FilterClass = "SIMCInstr"; let RowFields = ["PseudoInstr"]; diff --git a/llvm/lib/Target/R600/SIInstructions.td b/llvm/lib/Target/R600/SIInstructions.td index c650b5429c9d..1afb89bb42ae 100644 --- a/llvm/lib/Target/R600/SIInstructions.td +++ b/llvm/lib/Target/R600/SIInstructions.td @@ -509,29 +509,31 @@ def S_TTRACEDATA : SOPP <0x00000016, (ins), "s_ttracedata"> { let isCompare = 1 in { +let isCommutable = 1 in { defm V_CMP_F_F32 : VOPC_F32 , "v_cmp_f_f32">; -defm V_CMP_LT_F32 : VOPC_F32 , "v_cmp_lt_f32", COND_OLT>; +defm V_CMP_LT_F32 : VOPC_F32 , "v_cmp_lt_f32", COND_OLT, "v_cmp_gt_f32">; defm V_CMP_EQ_F32 : VOPC_F32 , "v_cmp_eq_f32", COND_OEQ>; -defm V_CMP_LE_F32 : VOPC_F32 , "v_cmp_le_f32", COND_OLE>; +defm V_CMP_LE_F32 : VOPC_F32 , "v_cmp_le_f32", COND_OLE, "v_cmp_ge_f32">; defm V_CMP_GT_F32 : VOPC_F32 , "v_cmp_gt_f32", COND_OGT>; defm V_CMP_LG_F32 : VOPC_F32 , "v_cmp_lg_f32", COND_ONE>; defm V_CMP_GE_F32 : VOPC_F32 , "v_cmp_ge_f32", COND_OGE>; defm V_CMP_O_F32 : VOPC_F32 , "v_cmp_o_f32", COND_O>; defm V_CMP_U_F32 : VOPC_F32 , "v_cmp_u_f32", COND_UO>; -defm V_CMP_NGE_F32 : VOPC_F32 , "v_cmp_nge_f32", COND_ULT>; +defm V_CMP_NGE_F32 : VOPC_F32 , "v_cmp_nge_f32", COND_ULT, "v_cmp_nle_f32">; defm V_CMP_NLG_F32 : VOPC_F32 , "v_cmp_nlg_f32", COND_UEQ>; -defm V_CMP_NGT_F32 : VOPC_F32 , "v_cmp_ngt_f32", COND_ULE>; +defm V_CMP_NGT_F32 : VOPC_F32 , "v_cmp_ngt_f32", COND_ULE, "v_cmp_nlt_f32">; defm V_CMP_NLE_F32 : VOPC_F32 , "v_cmp_nle_f32", COND_UGT>; defm V_CMP_NEQ_F32 : VOPC_F32 , "v_cmp_neq_f32", COND_UNE>; defm V_CMP_NLT_F32 : VOPC_F32 , "v_cmp_nlt_f32", COND_UGE>; defm V_CMP_TRU_F32 : VOPC_F32 , "v_cmp_tru_f32">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPX_F_F32 : VOPCX_F32 , "v_cmpx_f_f32">; -defm V_CMPX_LT_F32 : VOPCX_F32 , "v_cmpx_lt_f32">; +defm V_CMPX_LT_F32 : VOPCX_F32 , "v_cmpx_lt_f32", "v_cmpx_gt_f32">; defm V_CMPX_EQ_F32 : VOPCX_F32 , "v_cmpx_eq_f32">; -defm V_CMPX_LE_F32 : VOPCX_F32 , "v_cmpx_le_f32">; +defm V_CMPX_LE_F32 : VOPCX_F32 , "v_cmpx_le_f32", "v_cmpx_ge_f32">; defm V_CMPX_GT_F32 : VOPCX_F32 , "v_cmpx_gt_f32">; defm V_CMPX_LG_F32 : VOPCX_F32 , "v_cmpx_lg_f32">; defm V_CMPX_GE_F32 : VOPCX_F32 , "v_cmpx_ge_f32">; @@ -545,141 +547,149 @@ defm V_CMPX_NEQ_F32 : VOPCX_F32 , "v_cmpx_neq_f32">; defm V_CMPX_NLT_F32 : VOPCX_F32 , "v_cmpx_nlt_f32">; defm V_CMPX_TRU_F32 : VOPCX_F32 , "v_cmpx_tru_f32">; -} // End hasSideEffects = 1 +} // End hasSideEffects = 1, isCommutable = 1 +let isCommutable = 1 in { defm V_CMP_F_F64 : VOPC_F64 , "v_cmp_f_f64">; -defm V_CMP_LT_F64 : VOPC_F64 , "v_cmp_lt_f64", COND_OLT>; +defm V_CMP_LT_F64 : VOPC_F64 , "v_cmp_lt_f64", COND_OLT, "v_cmp_gt_f64">; defm V_CMP_EQ_F64 : VOPC_F64 , "v_cmp_eq_f64", COND_OEQ>; -defm V_CMP_LE_F64 : VOPC_F64 , "v_cmp_le_f64", COND_OLE>; +defm V_CMP_LE_F64 : VOPC_F64 , "v_cmp_le_f64", COND_OLE, "v_cmp_ge_f64">; defm V_CMP_GT_F64 : VOPC_F64 , "v_cmp_gt_f64", COND_OGT>; defm V_CMP_LG_F64 : VOPC_F64 , "v_cmp_lg_f64", COND_ONE>; defm V_CMP_GE_F64 : VOPC_F64 , "v_cmp_ge_f64", COND_OGE>; defm V_CMP_O_F64 : VOPC_F64 , "v_cmp_o_f64", COND_O>; defm V_CMP_U_F64 : VOPC_F64 , "v_cmp_u_f64", COND_UO>; -defm V_CMP_NGE_F64 : VOPC_F64 , "v_cmp_nge_f64", COND_ULT>; +defm V_CMP_NGE_F64 : VOPC_F64 , "v_cmp_nge_f64", COND_ULT, "v_cmp_nle_f64">; defm V_CMP_NLG_F64 : VOPC_F64 , "v_cmp_nlg_f64", COND_UEQ>; -defm V_CMP_NGT_F64 : VOPC_F64 , "v_cmp_ngt_f64", COND_ULE>; +defm V_CMP_NGT_F64 : VOPC_F64 , "v_cmp_ngt_f64", COND_ULE, "v_cmp_nlt_f64">; defm V_CMP_NLE_F64 : VOPC_F64 , "v_cmp_nle_f64", COND_UGT>; defm V_CMP_NEQ_F64 : VOPC_F64 , "v_cmp_neq_f64", COND_UNE>; defm V_CMP_NLT_F64 : VOPC_F64 , "v_cmp_nlt_f64", COND_UGE>; defm V_CMP_TRU_F64 : VOPC_F64 , "v_cmp_tru_f64">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPX_F_F64 : VOPCX_F64 , "v_cmpx_f_f64">; -defm V_CMPX_LT_F64 : VOPCX_F64 , "v_cmpx_lt_f64">; +defm V_CMPX_LT_F64 : VOPCX_F64 , "v_cmpx_lt_f64", "v_cmpx_gt_f64">; defm V_CMPX_EQ_F64 : VOPCX_F64 , "v_cmpx_eq_f64">; -defm V_CMPX_LE_F64 : VOPCX_F64 , "v_cmpx_le_f64">; +defm V_CMPX_LE_F64 : VOPCX_F64 , "v_cmpx_le_f64", "v_cmpx_ge_f64">; defm V_CMPX_GT_F64 : VOPCX_F64 , "v_cmpx_gt_f64">; defm V_CMPX_LG_F64 : VOPCX_F64 , "v_cmpx_lg_f64">; defm V_CMPX_GE_F64 : VOPCX_F64 , "v_cmpx_ge_f64">; defm V_CMPX_O_F64 : VOPCX_F64 , "v_cmpx_o_f64">; defm V_CMPX_U_F64 : VOPCX_F64 , "v_cmpx_u_f64">; -defm V_CMPX_NGE_F64 : VOPCX_F64 , "v_cmpx_nge_f64">; +defm V_CMPX_NGE_F64 : VOPCX_F64 , "v_cmpx_nge_f64", "v_cmpx_nle_f64">; defm V_CMPX_NLG_F64 : VOPCX_F64 , "v_cmpx_nlg_f64">; -defm V_CMPX_NGT_F64 : VOPCX_F64 , "v_cmpx_ngt_f64">; +defm V_CMPX_NGT_F64 : VOPCX_F64 , "v_cmpx_ngt_f64", "v_cmpx_nlt_f64">; defm V_CMPX_NLE_F64 : VOPCX_F64 , "v_cmpx_nle_f64">; defm V_CMPX_NEQ_F64 : VOPCX_F64 , "v_cmpx_neq_f64">; defm V_CMPX_NLT_F64 : VOPCX_F64 , "v_cmpx_nlt_f64">; defm V_CMPX_TRU_F64 : VOPCX_F64 , "v_cmpx_tru_f64">; -} // End hasSideEffects = 1 +} // End hasSideEffects = 1, isCommutable = 1 let SubtargetPredicate = isSICI in { +let isCommutable = 1 in { defm V_CMPS_F_F32 : VOPC_F32 , "v_cmps_f_f32">; -defm V_CMPS_LT_F32 : VOPC_F32 , "v_cmps_lt_f32">; +defm V_CMPS_LT_F32 : VOPC_F32 , "v_cmps_lt_f32", COND_NULL, "v_cmps_gt_f32">; defm V_CMPS_EQ_F32 : VOPC_F32 , "v_cmps_eq_f32">; -defm V_CMPS_LE_F32 : VOPC_F32 , "v_cmps_le_f32">; +defm V_CMPS_LE_F32 : VOPC_F32 , "v_cmps_le_f32", COND_NULL, "v_cmps_ge_f32">; defm V_CMPS_GT_F32 : VOPC_F32 , "v_cmps_gt_f32">; defm V_CMPS_LG_F32 : VOPC_F32 , "v_cmps_lg_f32">; defm V_CMPS_GE_F32 : VOPC_F32 , "v_cmps_ge_f32">; defm V_CMPS_O_F32 : VOPC_F32 , "v_cmps_o_f32">; defm V_CMPS_U_F32 : VOPC_F32 , "v_cmps_u_f32">; -defm V_CMPS_NGE_F32 : VOPC_F32 , "v_cmps_nge_f32">; +defm V_CMPS_NGE_F32 : VOPC_F32 , "v_cmps_nge_f32", COND_NULL, "v_cmps_nle_f32">; defm V_CMPS_NLG_F32 : VOPC_F32 , "v_cmps_nlg_f32">; -defm V_CMPS_NGT_F32 : VOPC_F32 , "v_cmps_ngt_f32">; +defm V_CMPS_NGT_F32 : VOPC_F32 , "v_cmps_ngt_f32", COND_NULL, "v_cmps_nlt_f32">; defm V_CMPS_NLE_F32 : VOPC_F32 , "v_cmps_nle_f32">; defm V_CMPS_NEQ_F32 : VOPC_F32 , "v_cmps_neq_f32">; defm V_CMPS_NLT_F32 : VOPC_F32 , "v_cmps_nlt_f32">; defm V_CMPS_TRU_F32 : VOPC_F32 , "v_cmps_tru_f32">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPSX_F_F32 : VOPCX_F32 , "v_cmpsx_f_f32">; -defm V_CMPSX_LT_F32 : VOPCX_F32 , "v_cmpsx_lt_f32">; +defm V_CMPSX_LT_F32 : VOPCX_F32 , "v_cmpsx_lt_f32", "v_cmpsx_gt_f32">; defm V_CMPSX_EQ_F32 : VOPCX_F32 , "v_cmpsx_eq_f32">; -defm V_CMPSX_LE_F32 : VOPCX_F32 , "v_cmpsx_le_f32">; +defm V_CMPSX_LE_F32 : VOPCX_F32 , "v_cmpsx_le_f32", "v_cmpsx_ge_f32">; defm V_CMPSX_GT_F32 : VOPCX_F32 , "v_cmpsx_gt_f32">; defm V_CMPSX_LG_F32 : VOPCX_F32 , "v_cmpsx_lg_f32">; defm V_CMPSX_GE_F32 : VOPCX_F32 , "v_cmpsx_ge_f32">; defm V_CMPSX_O_F32 : VOPCX_F32 , "v_cmpsx_o_f32">; defm V_CMPSX_U_F32 : VOPCX_F32 , "v_cmpsx_u_f32">; -defm V_CMPSX_NGE_F32 : VOPCX_F32 , "v_cmpsx_nge_f32">; +defm V_CMPSX_NGE_F32 : VOPCX_F32 , "v_cmpsx_nge_f32", "v_cmpsx_nle_f32">; defm V_CMPSX_NLG_F32 : VOPCX_F32 , "v_cmpsx_nlg_f32">; -defm V_CMPSX_NGT_F32 : VOPCX_F32 , "v_cmpsx_ngt_f32">; +defm V_CMPSX_NGT_F32 : VOPCX_F32 , "v_cmpsx_ngt_f32", "v_cmpsx_nlt_f32">; defm V_CMPSX_NLE_F32 : VOPCX_F32 , "v_cmpsx_nle_f32">; defm V_CMPSX_NEQ_F32 : VOPCX_F32 , "v_cmpsx_neq_f32">; defm V_CMPSX_NLT_F32 : VOPCX_F32 , "v_cmpsx_nlt_f32">; defm V_CMPSX_TRU_F32 : VOPCX_F32 , "v_cmpsx_tru_f32">; -} // End hasSideEffects = 1 +} // End hasSideEffects = 1, isCommutable = 1 +let isCommutable = 1 in { defm V_CMPS_F_F64 : VOPC_F64 , "v_cmps_f_f64">; -defm V_CMPS_LT_F64 : VOPC_F64 , "v_cmps_lt_f64">; +defm V_CMPS_LT_F64 : VOPC_F64 , "v_cmps_lt_f64", COND_NULL, "v_cmps_gt_f64">; defm V_CMPS_EQ_F64 : VOPC_F64 , "v_cmps_eq_f64">; -defm V_CMPS_LE_F64 : VOPC_F64 , "v_cmps_le_f64">; +defm V_CMPS_LE_F64 : VOPC_F64 , "v_cmps_le_f64", COND_NULL, "v_cmps_ge_f64">; defm V_CMPS_GT_F64 : VOPC_F64 , "v_cmps_gt_f64">; defm V_CMPS_LG_F64 : VOPC_F64 , "v_cmps_lg_f64">; defm V_CMPS_GE_F64 : VOPC_F64 , "v_cmps_ge_f64">; defm V_CMPS_O_F64 : VOPC_F64 , "v_cmps_o_f64">; defm V_CMPS_U_F64 : VOPC_F64 , "v_cmps_u_f64">; -defm V_CMPS_NGE_F64 : VOPC_F64 , "v_cmps_nge_f64">; +defm V_CMPS_NGE_F64 : VOPC_F64 , "v_cmps_nge_f64", COND_NULL, "v_cmps_nle_f64">; defm V_CMPS_NLG_F64 : VOPC_F64 , "v_cmps_nlg_f64">; -defm V_CMPS_NGT_F64 : VOPC_F64 , "v_cmps_ngt_f64">; +defm V_CMPS_NGT_F64 : VOPC_F64 , "v_cmps_ngt_f64", COND_NULL, "v_cmps_nlt_f64">; defm V_CMPS_NLE_F64 : VOPC_F64 , "v_cmps_nle_f64">; defm V_CMPS_NEQ_F64 : VOPC_F64 , "v_cmps_neq_f64">; defm V_CMPS_NLT_F64 : VOPC_F64 , "v_cmps_nlt_f64">; defm V_CMPS_TRU_F64 : VOPC_F64 , "v_cmps_tru_f64">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPSX_F_F64 : VOPCX_F64 , "v_cmpsx_f_f64">; -defm V_CMPSX_LT_F64 : VOPCX_F64 , "v_cmpsx_lt_f64">; +defm V_CMPSX_LT_F64 : VOPCX_F64 , "v_cmpsx_lt_f64", "v_cmpsx_gt_f64">; defm V_CMPSX_EQ_F64 : VOPCX_F64 , "v_cmpsx_eq_f64">; -defm V_CMPSX_LE_F64 : VOPCX_F64 , "v_cmpsx_le_f64">; +defm V_CMPSX_LE_F64 : VOPCX_F64 , "v_cmpsx_le_f64", "v_cmpsx_ge_f64">; defm V_CMPSX_GT_F64 : VOPCX_F64 , "v_cmpsx_gt_f64">; defm V_CMPSX_LG_F64 : VOPCX_F64 , "v_cmpsx_lg_f64">; defm V_CMPSX_GE_F64 : VOPCX_F64 , "v_cmpsx_ge_f64">; defm V_CMPSX_O_F64 : VOPCX_F64 , "v_cmpsx_o_f64">; defm V_CMPSX_U_F64 : VOPCX_F64 , "v_cmpsx_u_f64">; -defm V_CMPSX_NGE_F64 : VOPCX_F64 , "v_cmpsx_nge_f64">; +defm V_CMPSX_NGE_F64 : VOPCX_F64 , "v_cmpsx_nge_f64", "v_cmpsx_nle_f64">; defm V_CMPSX_NLG_F64 : VOPCX_F64 , "v_cmpsx_nlg_f64">; -defm V_CMPSX_NGT_F64 : VOPCX_F64 , "v_cmpsx_ngt_f64">; +defm V_CMPSX_NGT_F64 : VOPCX_F64 , "v_cmpsx_ngt_f64", "v_cmpsx_nlt_f64">; defm V_CMPSX_NLE_F64 : VOPCX_F64 , "v_cmpsx_nle_f64">; defm V_CMPSX_NEQ_F64 : VOPCX_F64 , "v_cmpsx_neq_f64">; defm V_CMPSX_NLT_F64 : VOPCX_F64 , "v_cmpsx_nlt_f64">; defm V_CMPSX_TRU_F64 : VOPCX_F64 , "v_cmpsx_tru_f64">; -} // End hasSideEffects = 1 +} // End hasSideEffects = 1, isCommutable = 1 } // End SubtargetPredicate = isSICI +let isCommutable = 1 in { defm V_CMP_F_I32 : VOPC_I32 , "v_cmp_f_i32">; -defm V_CMP_LT_I32 : VOPC_I32 , "v_cmp_lt_i32", COND_SLT>; +defm V_CMP_LT_I32 : VOPC_I32 , "v_cmp_lt_i32", COND_SLT, "v_cmp_gt_i32">; defm V_CMP_EQ_I32 : VOPC_I32 , "v_cmp_eq_i32", COND_EQ>; -defm V_CMP_LE_I32 : VOPC_I32 , "v_cmp_le_i32", COND_SLE>; +defm V_CMP_LE_I32 : VOPC_I32 , "v_cmp_le_i32", COND_SLE, "v_cmp_ge_i32">; defm V_CMP_GT_I32 : VOPC_I32 , "v_cmp_gt_i32", COND_SGT>; defm V_CMP_NE_I32 : VOPC_I32 , "v_cmp_ne_i32", COND_NE>; defm V_CMP_GE_I32 : VOPC_I32 , "v_cmp_ge_i32", COND_SGE>; defm V_CMP_T_I32 : VOPC_I32 , "v_cmp_t_i32">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPX_F_I32 : VOPCX_I32 , "v_cmpx_f_i32">; -defm V_CMPX_LT_I32 : VOPCX_I32 , "v_cmpx_lt_i32">; +defm V_CMPX_LT_I32 : VOPCX_I32 , "v_cmpx_lt_i32", "v_cmpx_gt_i32">; defm V_CMPX_EQ_I32 : VOPCX_I32 , "v_cmpx_eq_i32">; -defm V_CMPX_LE_I32 : VOPCX_I32 , "v_cmpx_le_i32">; +defm V_CMPX_LE_I32 : VOPCX_I32 , "v_cmpx_le_i32", "v_cmpx_ge_i32">; defm V_CMPX_GT_I32 : VOPCX_I32 , "v_cmpx_gt_i32">; defm V_CMPX_NE_I32 : VOPCX_I32 , "v_cmpx_ne_i32">; defm V_CMPX_GE_I32 : VOPCX_I32 , "v_cmpx_ge_i32">; @@ -687,71 +697,77 @@ defm V_CMPX_T_I32 : VOPCX_I32 , "v_cmpx_t_i32">; } // End hasSideEffects = 1 +let isCommutable = 1 in { defm V_CMP_F_I64 : VOPC_I64 , "v_cmp_f_i64">; -defm V_CMP_LT_I64 : VOPC_I64 , "v_cmp_lt_i64", COND_SLT>; +defm V_CMP_LT_I64 : VOPC_I64 , "v_cmp_lt_i64", COND_SLT, "v_cmp_gt_i64">; defm V_CMP_EQ_I64 : VOPC_I64 , "v_cmp_eq_i64", COND_EQ>; -defm V_CMP_LE_I64 : VOPC_I64 , "v_cmp_le_i64", COND_SLE>; +defm V_CMP_LE_I64 : VOPC_I64 , "v_cmp_le_i64", COND_SLE, "v_cmp_ge_i64">; defm V_CMP_GT_I64 : VOPC_I64 , "v_cmp_gt_i64", COND_SGT>; defm V_CMP_NE_I64 : VOPC_I64 , "v_cmp_ne_i64", COND_NE>; defm V_CMP_GE_I64 : VOPC_I64 , "v_cmp_ge_i64", COND_SGE>; defm V_CMP_T_I64 : VOPC_I64 , "v_cmp_t_i64">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPX_F_I64 : VOPCX_I64 , "v_cmpx_f_i64">; -defm V_CMPX_LT_I64 : VOPCX_I64 , "v_cmpx_lt_i64">; +defm V_CMPX_LT_I64 : VOPCX_I64 , "v_cmpx_lt_i64", "v_cmpx_gt_i64">; defm V_CMPX_EQ_I64 : VOPCX_I64 , "v_cmpx_eq_i64">; -defm V_CMPX_LE_I64 : VOPCX_I64 , "v_cmpx_le_i64">; +defm V_CMPX_LE_I64 : VOPCX_I64 , "v_cmpx_le_i64", "v_cmpx_ge_i64">; defm V_CMPX_GT_I64 : VOPCX_I64 , "v_cmpx_gt_i64">; defm V_CMPX_NE_I64 : VOPCX_I64 , "v_cmpx_ne_i64">; defm V_CMPX_GE_I64 : VOPCX_I64 , "v_cmpx_ge_i64">; defm V_CMPX_T_I64 : VOPCX_I64 , "v_cmpx_t_i64">; -} // End hasSideEffects = 1 +} // End hasSideEffects = 1, isCommutable = 1 +let isCommutable = 1 in { defm V_CMP_F_U32 : VOPC_I32 , "v_cmp_f_u32">; -defm V_CMP_LT_U32 : VOPC_I32 , "v_cmp_lt_u32", COND_ULT>; +defm V_CMP_LT_U32 : VOPC_I32 , "v_cmp_lt_u32", COND_ULT, "v_cmp_gt_u32">; defm V_CMP_EQ_U32 : VOPC_I32 , "v_cmp_eq_u32", COND_EQ>; -defm V_CMP_LE_U32 : VOPC_I32 , "v_cmp_le_u32", COND_ULE>; +defm V_CMP_LE_U32 : VOPC_I32 , "v_cmp_le_u32", COND_ULE, "v_cmp_ge_u32">; defm V_CMP_GT_U32 : VOPC_I32 , "v_cmp_gt_u32", COND_UGT>; defm V_CMP_NE_U32 : VOPC_I32 , "v_cmp_ne_u32", COND_NE>; defm V_CMP_GE_U32 : VOPC_I32 , "v_cmp_ge_u32", COND_UGE>; defm V_CMP_T_U32 : VOPC_I32 , "v_cmp_t_u32">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPX_F_U32 : VOPCX_I32 , "v_cmpx_f_u32">; -defm V_CMPX_LT_U32 : VOPCX_I32 , "v_cmpx_lt_u32">; +defm V_CMPX_LT_U32 : VOPCX_I32 , "v_cmpx_lt_u32", "v_cmpx_gt_u32">; defm V_CMPX_EQ_U32 : VOPCX_I32 , "v_cmpx_eq_u32">; -defm V_CMPX_LE_U32 : VOPCX_I32 , "v_cmpx_le_u32">; +defm V_CMPX_LE_U32 : VOPCX_I32 , "v_cmpx_le_u32", "v_cmpx_le_u32">; defm V_CMPX_GT_U32 : VOPCX_I32 , "v_cmpx_gt_u32">; defm V_CMPX_NE_U32 : VOPCX_I32 , "v_cmpx_ne_u32">; defm V_CMPX_GE_U32 : VOPCX_I32 , "v_cmpx_ge_u32">; defm V_CMPX_T_U32 : VOPCX_I32 , "v_cmpx_t_u32">; -} // End hasSideEffects = 1 +} // End hasSideEffects = 1, isCommutable = 1 +let isCommutable = 1 in { defm V_CMP_F_U64 : VOPC_I64 , "v_cmp_f_u64">; -defm V_CMP_LT_U64 : VOPC_I64 , "v_cmp_lt_u64", COND_ULT>; +defm V_CMP_LT_U64 : VOPC_I64 , "v_cmp_lt_u64", COND_ULT, "v_cmp_gt_u64">; defm V_CMP_EQ_U64 : VOPC_I64 , "v_cmp_eq_u64", COND_EQ>; -defm V_CMP_LE_U64 : VOPC_I64 , "v_cmp_le_u64", COND_ULE>; +defm V_CMP_LE_U64 : VOPC_I64 , "v_cmp_le_u64", COND_ULE, "v_cmp_ge_u64">; defm V_CMP_GT_U64 : VOPC_I64 , "v_cmp_gt_u64", COND_UGT>; defm V_CMP_NE_U64 : VOPC_I64 , "v_cmp_ne_u64", COND_NE>; defm V_CMP_GE_U64 : VOPC_I64 , "v_cmp_ge_u64", COND_UGE>; defm V_CMP_T_U64 : VOPC_I64 , "v_cmp_t_u64">; +} // End isCommutable = 1 -let hasSideEffects = 1 in { +let hasSideEffects = 1, isCommutable = 1 in { defm V_CMPX_F_U64 : VOPCX_I64 , "v_cmpx_f_u64">; -defm V_CMPX_LT_U64 : VOPCX_I64 , "v_cmpx_lt_u64">; +defm V_CMPX_LT_U64 : VOPCX_I64 , "v_cmpx_lt_u64", "v_cmpx_gt_u64">; defm V_CMPX_EQ_U64 : VOPCX_I64 , "v_cmpx_eq_u64">; -defm V_CMPX_LE_U64 : VOPCX_I64 , "v_cmpx_le_u64">; +defm V_CMPX_LE_U64 : VOPCX_I64 , "v_cmpx_le_u64", "v_cmpx_ge_u64">; defm V_CMPX_GT_U64 : VOPCX_I64 , "v_cmpx_gt_u64">; defm V_CMPX_NE_U64 : VOPCX_I64 , "v_cmpx_ne_u64">; defm V_CMPX_GE_U64 : VOPCX_I64 , "v_cmpx_ge_u64">; defm V_CMPX_T_U64 : VOPCX_I64 , "v_cmpx_t_u64">; -} // End hasSideEffects = 1 +} // End hasSideEffects = 1, isCommutable = 1 defm V_CMP_CLASS_F32 : VOPC_CLASS_F32 , "v_cmp_class_f32">; diff --git a/llvm/test/CodeGen/R600/commute-compares.ll b/llvm/test/CodeGen/R600/commute-compares.ll new file mode 100644 index 000000000000..31766047a358 --- /dev/null +++ b/llvm/test/CodeGen/R600/commute-compares.ll @@ -0,0 +1,697 @@ +; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s + +declare i32 @llvm.r600.read.tidig.x() #0 + +; -------------------------------------------------------------------------------- +; i32 compares +; -------------------------------------------------------------------------------- + +; GCN-LABEL: {{^}}commute_eq_64_i32: +; GCN: v_cmp_eq_i32_e32 vcc, 64, v{{[0-9]+}} +define void @commute_eq_64_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp eq i32 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ne_64_i32: +; GCN: v_cmp_ne_i32_e32 vcc, 64, v{{[0-9]+}} +define void @commute_ne_64_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp ne i32 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; FIXME: Why isn't this being folded as a constant? +; GCN-LABEL: {{^}}commute_ne_litk_i32: +; GCN: v_mov_b32_e32 [[K:v[0-9]+]], 0x3039 +; GCN: v_cmp_ne_i32_e32 vcc, [[K]], v{{[0-9]+}} +define void @commute_ne_litk_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp ne i32 %val, 12345 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ugt_64_i32: +; GCN: v_cmp_lt_u32_e32 vcc, 64, v{{[0-9]+}} +define void @commute_ugt_64_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp ugt i32 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_uge_64_i32: +; GCN: v_cmp_lt_u32_e32 vcc, 63, v{{[0-9]+}} +define void @commute_uge_64_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp uge i32 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ult_64_i32: +; GCN: v_cmp_gt_u32_e32 vcc, 64, v{{[0-9]+}} +define void @commute_ult_64_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp ult i32 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ule_63_i32: +; GCN: v_cmp_gt_u32_e32 vcc, 64, v{{[0-9]+}} +define void @commute_ule_63_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp ule i32 %val, 63 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; FIXME: Undo canonicalization to gt (x + 1) since it doesn't use the inline imm + +; GCN-LABEL: {{^}}commute_ule_64_i32: +; GCN: v_mov_b32_e32 [[K:v[0-9]+]], 0x41{{$}} +; GCN: v_cmp_gt_u32_e32 vcc, [[K]], v{{[0-9]+}} +define void @commute_ule_64_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp ule i32 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_sgt_neg1_i32: +; GCN: v_cmp_lt_i32_e32 vcc, -1, v{{[0-9]+}} +define void @commute_sgt_neg1_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp sgt i32 %val, -1 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_sge_neg2_i32: +; GCN: v_cmp_lt_i32_e32 vcc, -3, v{{[0-9]+}} +define void @commute_sge_neg2_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp sge i32 %val, -2 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_slt_neg16_i32: +; GCN: v_cmp_gt_i32_e32 vcc, -16, v{{[0-9]+}} +define void @commute_slt_neg16_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp slt i32 %val, -16 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_sle_5_i32: +; GCN: v_cmp_gt_i32_e32 vcc, 6, v{{[0-9]+}} +define void @commute_sle_5_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i32, i32 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i32, i32 addrspace(1)* %gep.in + %cmp = icmp sle i32 %val, 5 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; -------------------------------------------------------------------------------- +; i64 compares +; -------------------------------------------------------------------------------- + +; GCN-LABEL: {{^}}commute_eq_64_i64: +; GCN: v_cmp_eq_i64_e32 vcc, 64, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_eq_64_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp eq i64 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ne_64_i64: +; GCN: v_cmp_ne_i64_e32 vcc, 64, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ne_64_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp ne i64 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ugt_64_i64: +; GCN: v_cmp_lt_u64_e32 vcc, 64, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ugt_64_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp ugt i64 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_uge_64_i64: +; GCN: v_cmp_lt_u64_e32 vcc, 63, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_uge_64_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp uge i64 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ult_64_i64: +; GCN: v_cmp_gt_u64_e32 vcc, 64, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ult_64_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp ult i64 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ule_63_i64: +; GCN: v_cmp_gt_u64_e32 vcc, 64, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ule_63_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp ule i64 %val, 63 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; FIXME: Undo canonicalization to gt (x + 1) since it doesn't use the inline imm + +; GCN-LABEL: {{^}}commute_ule_64_i64: +; GCN-DAG: s_movk_i32 s[[KLO:[0-9]+]], 0x41{{$}} +; GCN: v_cmp_gt_u64_e32 vcc, s{{\[}}[[KLO]]:{{[0-9]+\]}}, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ule_64_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp ule i64 %val, 64 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_sgt_neg1_i64: +; GCN: v_cmp_lt_i64_e32 vcc, -1, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_sgt_neg1_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp sgt i64 %val, -1 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_sge_neg2_i64: +; GCN: v_cmp_lt_i64_e32 vcc, -3, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_sge_neg2_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp sge i64 %val, -2 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_slt_neg16_i64: +; GCN: v_cmp_gt_i64_e32 vcc, -16, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_slt_neg16_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp slt i64 %val, -16 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_sle_5_i64: +; GCN: v_cmp_gt_i64_e32 vcc, 6, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_sle_5_i64(i32 addrspace(1)* %out, i64 addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr i64, i64 addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load i64, i64 addrspace(1)* %gep.in + %cmp = icmp sle i64 %val, 5 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; -------------------------------------------------------------------------------- +; f32 compares +; -------------------------------------------------------------------------------- + + +; GCN-LABEL: {{^}}commute_oeq_2.0_f32: +; GCN: v_cmp_eq_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_oeq_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp oeq float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + + +; GCN-LABEL: {{^}}commute_ogt_2.0_f32: +; GCN: v_cmp_lt_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_ogt_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp ogt float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_oge_2.0_f32: +; GCN: v_cmp_le_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_oge_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp oge float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_olt_2.0_f32: +; GCN: v_cmp_gt_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_olt_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp olt float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ole_2.0_f32: +; GCN: v_cmp_ge_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_ole_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp ole float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_one_2.0_f32: +; GCN: v_cmp_lg_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_one_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp one float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ord_2.0_f32: +; GCN: v_cmp_o_f32_e32 vcc, [[REG:v[0-9]+]], [[REG]] +define void @commute_ord_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp ord float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ueq_2.0_f32: +; GCN: v_cmp_nlg_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_ueq_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp ueq float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ugt_2.0_f32: +; GCN: v_cmp_nge_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_ugt_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp ugt float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_uge_2.0_f32: +; GCN: v_cmp_ngt_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_uge_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp uge float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ult_2.0_f32: +; GCN: v_cmp_nle_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_ult_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp ult float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ule_2.0_f32: +; GCN: v_cmp_nlt_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_ule_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp ule float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_une_2.0_f32: +; GCN: v_cmp_neq_f32_e32 vcc, 2.0, v{{[0-9]+}} +define void @commute_une_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp une float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_uno_2.0_f32: +; GCN: v_cmp_u_f32_e32 vcc, [[REG:v[0-9]+]], [[REG]] +define void @commute_uno_2.0_f32(i32 addrspace(1)* %out, float addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr float, float addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load float, float addrspace(1)* %gep.in + %cmp = fcmp uno float %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; -------------------------------------------------------------------------------- +; f64 compares +; -------------------------------------------------------------------------------- + + +; GCN-LABEL: {{^}}commute_oeq_2.0_f64: +; GCN: v_cmp_eq_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_oeq_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp oeq double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + + +; GCN-LABEL: {{^}}commute_ogt_2.0_f64: +; GCN: v_cmp_lt_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ogt_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp ogt double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_oge_2.0_f64: +; GCN: v_cmp_le_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_oge_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp oge double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_olt_2.0_f64: +; GCN: v_cmp_gt_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_olt_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp olt double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ole_2.0_f64: +; GCN: v_cmp_ge_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ole_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp ole double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_one_2.0_f64: +; GCN: v_cmp_lg_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_one_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp one double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ord_2.0_f64: +; GCN: v_cmp_o_f64_e32 vcc, [[REG:v\[[0-9]+:[0-9]+\]]], [[REG]] +define void @commute_ord_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp ord double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ueq_2.0_f64: +; GCN: v_cmp_nlg_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ueq_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp ueq double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ugt_2.0_f64: +; GCN: v_cmp_nge_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ugt_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp ugt double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_uge_2.0_f64: +; GCN: v_cmp_ngt_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_uge_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp uge double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ult_2.0_f64: +; GCN: v_cmp_nle_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ult_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp ult double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_ule_2.0_f64: +; GCN: v_cmp_nlt_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_ule_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp ule double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_une_2.0_f64: +; GCN: v_cmp_neq_f64_e32 vcc, 2.0, v{{\[[0-9]+:[0-9]+\]}} +define void @commute_une_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp une double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +; GCN-LABEL: {{^}}commute_uno_2.0_f64: +; GCN: v_cmp_u_f64_e32 vcc, [[REG:v\[[0-9]+:[0-9]+\]]], [[REG]] +define void @commute_uno_2.0_f64(i32 addrspace(1)* %out, double addrspace(1)* %in) #1 { + %tid = call i32 @llvm.r600.read.tidig.x() #0 + %gep.in = getelementptr double, double addrspace(1)* %in, i32 %tid + %gep.out = getelementptr i32, i32 addrspace(1)* %out, i32 %tid + %val = load double, double addrspace(1)* %gep.in + %cmp = fcmp uno double %val, 2.0 + %ext = sext i1 %cmp to i32 + store i32 %ext, i32 addrspace(1)* %gep.out + ret void +} + +attributes #0 = { nounwind readnone } +attributes #1 = { nounwind } diff --git a/llvm/test/CodeGen/R600/fceil64.ll b/llvm/test/CodeGen/R600/fceil64.ll index e3244fa2903a..e8c34f0141e4 100644 --- a/llvm/test/CodeGen/R600/fceil64.ll +++ b/llvm/test/CodeGen/R600/fceil64.ll @@ -17,13 +17,13 @@ declare <16 x double> @llvm.ceil.v16f64(<16 x double>) nounwind readnone ; SI: s_lshr_b64 ; SI: s_not_b64 ; SI: s_and_b64 -; SI: cmp_lt_i32 -; SI: cndmask_b32 -; SI: cndmask_b32 ; SI: cmp_gt_i32 ; SI: cndmask_b32 ; SI: cndmask_b32 -; SI-DAG: v_cmp_gt_f64 +; SI: cmp_lt_i32 +; SI: cndmask_b32 +; SI: cndmask_b32 +; SI-DAG: v_cmp_lt_f64 ; SI-DAG: v_cmp_lg_f64 ; SI: s_and_b64 ; SI: v_cndmask_b32 diff --git a/llvm/test/CodeGen/R600/ffloor.f64.ll b/llvm/test/CodeGen/R600/ffloor.f64.ll index 745ad3b47395..f3cbce13cf45 100644 --- a/llvm/test/CodeGen/R600/ffloor.f64.ll +++ b/llvm/test/CodeGen/R600/ffloor.f64.ll @@ -18,13 +18,13 @@ declare <16 x double> @llvm.floor.v16f64(<16 x double>) nounwind readnone ; SI: s_lshr_b64 ; SI: s_not_b64 ; SI: s_and_b64 -; SI: cmp_lt_i32 -; SI: cndmask_b32 -; SI: cndmask_b32 ; SI: cmp_gt_i32 ; SI: cndmask_b32 ; SI: cndmask_b32 -; SI-DAG: v_cmp_lt_f64 +; SI: cmp_lt_i32 +; SI: cndmask_b32 +; SI: cndmask_b32 +; SI-DAG: v_cmp_gt_f64 ; SI-DAG: v_cmp_lg_f64 ; SI-DAG: s_and_b64 ; SI-DAG: v_cndmask_b32 diff --git a/llvm/test/CodeGen/R600/ftrunc.f64.ll b/llvm/test/CodeGen/R600/ftrunc.f64.ll index dd51f6428d67..4ea84a7ea4bc 100644 --- a/llvm/test/CodeGen/R600/ftrunc.f64.ll +++ b/llvm/test/CodeGen/R600/ftrunc.f64.ll @@ -27,12 +27,12 @@ define void @v_ftrunc_f64(double addrspace(1)* %out, double addrspace(1)* %in) { ; SI: s_and_b32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80000000 ; SI: s_add_i32 s{{[0-9]+}}, [[SEXP]], 0xfffffc01 ; SI: s_lshr_b64 -; SI: cmp_lt_i32 +; SI: cmp_gt_i32 ; SI: s_not_b64 ; SI: s_and_b64 ; SI: cndmask_b32 ; SI: cndmask_b32 -; SI: cmp_gt_i32 +; SI: cmp_lt_i32 ; SI: cndmask_b32 ; SI: cndmask_b32 ; SI: s_endpgm diff --git a/llvm/test/CodeGen/R600/i1-copy-phi.ll b/llvm/test/CodeGen/R600/i1-copy-phi.ll index 430466e9f80e..105cd06b330a 100644 --- a/llvm/test/CodeGen/R600/i1-copy-phi.ll +++ b/llvm/test/CodeGen/R600/i1-copy-phi.ll @@ -6,7 +6,7 @@ ; SI: s_and_saveexec_b64 ; SI: s_xor_b64 ; SI: v_mov_b32_e32 [[REG]], -1{{$}} -; SI: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[REG]], 0 +; SI: v_cmp_ne_i32_e32 vcc, 0, [[REG]] ; SI: s_and_saveexec_b64 ; SI: s_xor_b64 ; SI: s_endpgm diff --git a/llvm/test/CodeGen/R600/llvm.AMDGPU.div_fmas.ll b/llvm/test/CodeGen/R600/llvm.AMDGPU.div_fmas.ll index 48a4af17d6f2..bcb7f870f1f4 100644 --- a/llvm/test/CodeGen/R600/llvm.AMDGPU.div_fmas.ll +++ b/llvm/test/CodeGen/R600/llvm.AMDGPU.div_fmas.ll @@ -78,7 +78,7 @@ define void @test_div_fmas_f64(double addrspace(1)* %out, double %a, double %b, } ; GCN-LABEL: {{^}}test_div_fmas_f32_cond_to_vcc: -; SI: v_cmp_eq_i32_e64 vcc, s{{[0-9]+}}, 0 +; SI: v_cmp_eq_i32_e64 vcc, 0, s{{[0-9]+}} ; SI: v_div_fmas_f32 {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}} define void @test_div_fmas_f32_cond_to_vcc(float addrspace(1)* %out, float %a, float %b, float %c, i32 %i) nounwind { %cmp = icmp eq i32 %i, 0 @@ -110,8 +110,8 @@ define void @test_div_fmas_f32_imm_true_cond_to_vcc(float addrspace(1)* %out, fl ; SI-DAG: buffer_load_dword [[B:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4{{$}} ; SI-DAG: buffer_load_dword [[C:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:8{{$}} -; SI-DAG: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], v{{[0-9]+}}, 0 -; SI-DAG: v_cmp_ne_i32_e64 [[CMP1:s\[[0-9]+:[0-9]+\]]], s{{[0-9]+}}, 0 +; SI-DAG: v_cmp_eq_i32_e32 [[CMP0:vcc]], 0, v{{[0-9]+}} +; SI-DAG: v_cmp_ne_i32_e64 [[CMP1:s\[[0-9]+:[0-9]+\]]], 0, s{{[0-9]+}} ; SI: s_and_b64 vcc, [[CMP0]], [[CMP1]] ; SI: v_div_fmas_f32 {{v[0-9]+}}, [[A]], [[B]], [[C]] ; SI: s_endpgm @@ -136,17 +136,17 @@ define void @test_div_fmas_f32_logical_cond_to_vcc(float addrspace(1)* %out, flo } ; GCN-LABEL: {{^}}test_div_fmas_f32_i1_phi_vcc: -; SI: v_cmp_eq_i32_e64 [[CMPTID:s\[[0-9]+:[0-9]+\]]], v{{[0-9]+}}, 0 -; SI: s_and_saveexec_b64 [[CMPTID]], [[CMPTID]] -; SI: s_xor_b64 [[CMPTID]], exec, [[CMPTID]] +; SI: v_cmp_eq_i32_e32 vcc, 0, v{{[0-9]+}} +; SI: s_and_saveexec_b64 [[SAVE:s\[[0-9]+:[0-9]+\]]], vcc +; SI: s_xor_b64 [[SAVE]], exec, [[SAVE]] ; SI: buffer_load_dword [[LOAD:v[0-9]+]] -; SI: v_cmp_ne_i32_e64 [[CMPLOAD:s\[[0-9]+:[0-9]+\]]], [[LOAD]], 0 -; SI: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1, [[CMPLOAD]] +; SI: v_cmp_ne_i32_e32 vcc, 0, [[LOAD]] +; SI: v_cndmask_b32_e64 {{v[0-9]+}}, 0, -1, vcc ; SI: BB9_2: -; SI: s_or_b64 exec, exec, [[CMPTID]] +; SI: s_or_b64 exec, exec, [[SAVE]] ; SI: v_cmp_ne_i32_e32 vcc, 0, v0 ; SI: v_div_fmas_f32 {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}} ; SI: buffer_store_dword diff --git a/llvm/test/CodeGen/R600/llvm.round.f64.ll b/llvm/test/CodeGen/R600/llvm.round.f64.ll index 7d082a24dd6d..3d0f57e33280 100644 --- a/llvm/test/CodeGen/R600/llvm.round.f64.ll +++ b/llvm/test/CodeGen/R600/llvm.round.f64.ll @@ -21,7 +21,7 @@ define void @round_f64(double addrspace(1)* %out, double %x) #0 { ; SI-DAG: v_cmp_eq_i32 ; SI-DAG: s_mov_b32 [[BFIMASK:s[0-9]+]], 0x7fffffff -; SI-DAG: v_cmp_lt_i32_e64 +; SI-DAG: v_cmp_gt_i32_e64 ; SI-DAG: v_bfi_b32 [[COPYSIGN:v[0-9]+]], [[BFIMASK]] ; SI-DAG: v_cmp_gt_i32_e64 diff --git a/llvm/test/CodeGen/R600/llvm.round.ll b/llvm/test/CodeGen/R600/llvm.round.ll index 8d1cfb67e40f..f5f124d915a5 100644 --- a/llvm/test/CodeGen/R600/llvm.round.ll +++ b/llvm/test/CodeGen/R600/llvm.round.ll @@ -9,7 +9,7 @@ ; SI: v_sub_f32_e32 [[SUB:v[0-9]+]], [[SX]], [[TRUNC]] ; SI: v_mov_b32_e32 [[VX:v[0-9]+]], [[SX]] ; SI: v_bfi_b32 [[COPYSIGN:v[0-9]+]], [[K]], 1.0, [[VX]] -; SI: v_cmp_ge_f32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], |[[SUB]]|, 0.5 +; SI: v_cmp_le_f32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], 0.5, |[[SUB]]| ; SI: v_cndmask_b32_e64 [[SEL:v[0-9]+]], 0, [[VX]], [[CMP]] ; SI: v_add_f32_e32 [[RESULT:v[0-9]+]], [[SEL]], [[TRUNC]] ; SI: buffer_store_dword [[RESULT]] diff --git a/llvm/test/CodeGen/R600/or.ll b/llvm/test/CodeGen/R600/or.ll index 1337adb7b453..1c04090b407f 100644 --- a/llvm/test/CodeGen/R600/or.ll +++ b/llvm/test/CodeGen/R600/or.ll @@ -155,7 +155,7 @@ define void @trunc_i64_or_to_i32(i32 addrspace(1)* %out, i64 %a, i64 %b) { ; FUNC-LABEL: {{^}}or_i1: ; EG: OR_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW], PS}} -; SI: s_or_b64 s[{{[0-9]+:[0-9]+}}], s[{{[0-9]+:[0-9]+}}], s[{{[0-9]+:[0-9]+}}] +; SI: s_or_b64 s[{{[0-9]+:[0-9]+}}], vcc, s[{{[0-9]+:[0-9]+}}] define void @or_i1(i32 addrspace(1)* %out, float addrspace(1)* %in0, float addrspace(1)* %in1) { %a = load float, float addrspace(1)* %in0 %b = load float, float addrspace(1)* %in1 diff --git a/llvm/test/CodeGen/R600/setcc-opt.ll b/llvm/test/CodeGen/R600/setcc-opt.ll index 0219cdb51049..4e6a10d6b78d 100644 --- a/llvm/test/CodeGen/R600/setcc-opt.ll +++ b/llvm/test/CodeGen/R600/setcc-opt.ll @@ -40,7 +40,7 @@ define void @sext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind ; FUNC-LABEL: {{^}}sext_bool_icmp_eq_1: ; GCN: v_cmp_eq_i32_e32 vcc, ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc -; GCN-NEXT: v_cmp_eq_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}} +; GCN-NEXT: v_cmp_eq_i32_e32 vcc, 1, [[TMP]]{{$}} ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1, ; GCN-NEXT: buffer_store_byte [[TMP]] ; GCN-NEXT: s_endpgm @@ -56,7 +56,7 @@ define void @sext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_1: ; GCN: v_cmp_ne_i32_e32 vcc, ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc -; GCN-NEXT: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}} +; GCN-NEXT: v_cmp_ne_i32_e32 vcc, 1, [[TMP]]{{$}} ; GCN-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1, ; GCN-NEXT: buffer_store_byte [[TMP]] ; GCN-NEXT: s_endpgm @@ -129,8 +129,8 @@ define void @zext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind ; VI-DAG: s_load_dword [[A:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x2c ; VI-DAG: s_load_dword [[B:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x30 ; GCN: v_mov_b32_e32 [[VB:v[0-9]+]], [[B]] -; GCN: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[VB]], 2{{$}} -; GCN: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]] +; GCN: v_cmp_ne_i32_e32 vcc, 2, [[VB]]{{$}} +; GCN: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc ; GCN: buffer_store_byte ; GCN: s_endpgm define void @sext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind { @@ -144,7 +144,7 @@ define void @sext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind ; FUNC-LABEL: {{^}}cmp_zext_k_i8max: ; GCN: buffer_load_ubyte [[B:v[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:44 ; GCN: v_mov_b32_e32 [[K255:v[0-9]+]], 0xff{{$}} -; GCN: v_cmp_ne_i32_e32 vcc, [[B]], [[K255]] +; GCN: v_cmp_ne_i32_e32 vcc, [[K255]], [[B]] ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc ; GCN-NEXT: buffer_store_byte [[RESULT]] ; GCN: s_endpgm @@ -157,8 +157,8 @@ define void @cmp_zext_k_i8max(i1 addrspace(1)* %out, i8 %b) nounwind { ; FUNC-LABEL: {{^}}cmp_sext_k_neg1: ; GCN: buffer_load_sbyte [[B:v[0-9]+]] -; GCN: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}} -; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]] +; GCN: v_cmp_ne_i32_e32 vcc, -1, [[B]]{{$}} +; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc ; GCN-NEXT: buffer_store_byte [[RESULT]] ; GCN: s_endpgm define void @cmp_sext_k_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %b.ptr) nounwind { @@ -171,7 +171,7 @@ define void @cmp_sext_k_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %b.ptr) nou ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_sext_arg: ; GCN: s_load_dword [[B:s[0-9]+]] -; GCN: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}} +; GCN: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], -1, [[B]] ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]] ; GCN-NEXT: buffer_store_byte [[RESULT]] ; GCN: s_endpgm @@ -189,7 +189,7 @@ define void @cmp_sext_k_neg1_i8_sext_arg(i1 addrspace(1)* %out, i8 signext %b) n ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_arg: ; GCN-DAG: buffer_load_ubyte [[B:v[0-9]+]] ; GCN-DAG: v_mov_b32_e32 [[K:v[0-9]+]], 0xff{{$}} -; GCN: v_cmp_ne_i32_e32 vcc, [[B]], [[K]]{{$}} +; GCN: v_cmp_ne_i32_e32 vcc, [[K]], [[B]]{{$}} ; GCN-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc ; GCN-NEXT: buffer_store_byte [[RESULT]] ; GCN: s_endpgm diff --git a/llvm/test/CodeGen/R600/sgpr-control-flow.ll b/llvm/test/CodeGen/R600/sgpr-control-flow.ll index fae7cd226e4f..38289ced632a 100644 --- a/llvm/test/CodeGen/R600/sgpr-control-flow.ll +++ b/llvm/test/CodeGen/R600/sgpr-control-flow.ll @@ -64,15 +64,15 @@ endif: ; SI-LABEL: {{^}}sgpr_if_else_valu_cmp_phi_br: ; SI: buffer_load_dword [[AVAL:v[0-9]+]] -; SI: v_cmp_lt_i32_e64 [[CMP_IF:s\[[0-9]+:[0-9]+\]]], [[AVAL]], 0 +; SI: v_cmp_gt_i32_e32 [[CMP_IF:vcc]], 0, [[AVAL]] ; SI: v_cndmask_b32_e64 [[V_CMP:v[0-9]+]], 0, -1, [[CMP_IF]] ; SI: BB2_1: ; SI: buffer_load_dword [[AVAL:v[0-9]+]] -; SI: v_cmp_eq_i32_e64 [[CMP_ELSE:s\[[0-9]+:[0-9]+\]]], [[AVAL]], 0 +; SI: v_cmp_eq_i32_e32 [[CMP_ELSE:vcc]], 0, [[AVAL]] ; SI: v_cndmask_b32_e64 [[V_CMP]], 0, -1, [[CMP_ELSE]] -; SI: v_cmp_ne_i32_e64 [[CMP_CMP:s\[[0-9]+:[0-9]+\]]], [[V_CMP]], 0 +; SI: v_cmp_ne_i32_e32 [[CMP_CMP:vcc]], 0, [[V_CMP]] ; SI: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, -1, [[CMP_CMP]] ; SI: buffer_store_dword [[RESULT]] define void @sgpr_if_else_valu_cmp_phi_br(i32 addrspace(1)* %out, i32 addrspace(1)* %a, i32 addrspace(1)* %b) { diff --git a/llvm/test/CodeGen/R600/trunc-cmp-constant.ll b/llvm/test/CodeGen/R600/trunc-cmp-constant.ll index 21dfade40366..dac74728b3ce 100644 --- a/llvm/test/CodeGen/R600/trunc-cmp-constant.ll +++ b/llvm/test/CodeGen/R600/trunc-cmp-constant.ll @@ -4,8 +4,8 @@ ; FUNC-LABEL {{^}}sextload_i1_to_i32_trunc_cmp_eq_0: ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]] ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]] -; SI: v_cmp_eq_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}} -; SI: s_xor_b64 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, -1{{$}} +; SI: v_cmp_eq_i32_e32 vcc, 1, [[TMP]]{{$}} +; SI: s_xor_b64 s{{\[[0-9]+:[0-9]+\]}}, vcc, -1{{$}} ; SI: v_cndmask_b32_e64 ; SI: buffer_store_byte define void @sextload_i1_to_i32_trunc_cmp_eq_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind { @@ -20,8 +20,8 @@ define void @sextload_i1_to_i32_trunc_cmp_eq_0(i1 addrspace(1)* %out, i1 addrspa ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_eq_0: ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]] ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]] -; SI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}} -; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], [[CMP0]], -1 +; SI: v_cmp_eq_i32_e32 vcc, 1, [[TMP]]{{$}} +; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], vcc, -1 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[NEG]] ; SI-NEXT: buffer_store_byte [[RESULT]] define void @zextload_i1_to_i32_trunc_cmp_eq_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind { @@ -117,8 +117,8 @@ define void @sextload_i1_to_i32_trunc_cmp_ne_1(i1 addrspace(1)* %out, i1 addrspa ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_ne_1: ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]] ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]] -; SI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}} -; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], [[CMP0]], -1 +; SI: v_cmp_eq_i32_e32 vcc, 1, [[TMP]]{{$}} +; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], vcc, -1 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[NEG]] ; SI-NEXT: buffer_store_byte [[RESULT]] define void @zextload_i1_to_i32_trunc_cmp_ne_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind { @@ -157,7 +157,7 @@ define void @zextload_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i1 addr ; FUNC-LABEL: {{^}}masked_load_i1_to_i32_trunc_cmp_ne_neg1: ; SI: buffer_load_sbyte [[LOAD:v[0-9]+]] -; SI: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[LOAD]], -1{{$}} +; SI: v_cmp_ne_i32_e32 vcc, -1, [[LOAD]]{{$}} ; SI-NEXT: v_cndmask_b32_e64 ; SI-NEXT: buffer_store_byte define void @masked_load_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %in) nounwind { diff --git a/llvm/test/CodeGen/R600/trunc.ll b/llvm/test/CodeGen/R600/trunc.ll index 5580bd3b1e86..bf690ca4cb28 100644 --- a/llvm/test/CodeGen/R600/trunc.ll +++ b/llvm/test/CodeGen/R600/trunc.ll @@ -73,8 +73,8 @@ define void @sgpr_trunc_i32_to_i1(i32 addrspace(1)* %out, i32 %a) { ; SI-LABEL: {{^}}s_trunc_i64_to_i1: ; SI: s_load_dwordx2 s{{\[}}[[SLO:[0-9]+]]:{{[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0xb ; SI: v_and_b32_e64 [[MASKED:v[0-9]+]], 1, s[[SLO]] -; SI: v_cmp_eq_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[MASKED]], 1 -; SI: v_cndmask_b32_e64 {{v[0-9]+}}, -12, 63, [[CMP]] +; SI: v_cmp_eq_i32_e32 vcc, 1, [[MASKED]] +; SI: v_cndmask_b32_e64 {{v[0-9]+}}, -12, 63, vcc define void @s_trunc_i64_to_i1(i32 addrspace(1)* %out, i64 %x) { %trunc = trunc i64 %x to i1 %sel = select i1 %trunc, i32 63, i32 -12 @@ -85,8 +85,8 @@ define void @s_trunc_i64_to_i1(i32 addrspace(1)* %out, i64 %x) { ; SI-LABEL: {{^}}v_trunc_i64_to_i1: ; SI: buffer_load_dwordx2 v{{\[}}[[VLO:[0-9]+]]:{{[0-9]+\]}} ; SI: v_and_b32_e32 [[MASKED:v[0-9]+]], 1, v[[VLO]] -; SI: v_cmp_eq_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[MASKED]], 1 -; SI: v_cndmask_b32_e64 {{v[0-9]+}}, -12, 63, [[CMP]] +; SI: v_cmp_eq_i32_e32 vcc, 1, [[MASKED]] +; SI: v_cndmask_b32_e64 {{v[0-9]+}}, -12, 63, vcc define void @v_trunc_i64_to_i1(i32 addrspace(1)* %out, i64 addrspace(1)* %in) { %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone %gep = getelementptr i64, i64 addrspace(1)* %in, i32 %tid diff --git a/llvm/test/CodeGen/R600/valu-i1.ll b/llvm/test/CodeGen/R600/valu-i1.ll index ef4f3ef0875b..7d0ebd139f51 100644 --- a/llvm/test/CodeGen/R600/valu-i1.ll +++ b/llvm/test/CodeGen/R600/valu-i1.ll @@ -42,8 +42,8 @@ end: } ; SI-LABEL: @simple_test_v_if -; SI: v_cmp_ne_i32_e64 [[BR_SREG:s\[[0-9]+:[0-9]+\]]], v{{[0-9]+}}, 0 -; SI: s_and_saveexec_b64 [[BR_SREG]], [[BR_SREG]] +; SI: v_cmp_ne_i32_e32 vcc, 0, v{{[0-9]+}} +; SI: s_and_saveexec_b64 [[BR_SREG:s\[[0-9]+:[0-9]+\]]], vcc ; SI: s_xor_b64 [[BR_SREG]], exec, [[BR_SREG]] ; SI: ; BB#1 @@ -68,8 +68,8 @@ exit: } ; SI-LABEL: @simple_test_v_loop -; SI: v_cmp_ne_i32_e64 [[BR_SREG:s\[[0-9]+:[0-9]+\]]], v{{[0-9]+}}, 0 -; SI: s_and_saveexec_b64 [[BR_SREG]], [[BR_SREG]] +; SI: v_cmp_ne_i32_e32 vcc, 0, v{{[0-9]+}} +; SI: s_and_saveexec_b64 [[BR_SREG:s\[[0-9]+:[0-9]+\]]], vcc ; SI: s_xor_b64 [[BR_SREG]], exec, [[BR_SREG]] ; SI: s_cbranch_execz BB2_2 @@ -111,8 +111,8 @@ exit: ; Branch to exit if uniformly not taken ; SI: ; BB#0: ; SI: buffer_load_dword [[VBOUND:v[0-9]+]] -; SI: v_cmp_gt_i32_e64 [[OUTER_CMP_SREG:s\[[0-9]+:[0-9]+\]]] -; SI: s_and_saveexec_b64 [[OUTER_CMP_SREG]], [[OUTER_CMP_SREG]] +; SI: v_cmp_lt_i32_e32 vcc +; SI: s_and_saveexec_b64 [[OUTER_CMP_SREG:s\[[0-9]+:[0-9]+\]]], vcc ; SI: s_xor_b64 [[OUTER_CMP_SREG]], exec, [[OUTER_CMP_SREG]] ; SI: s_cbranch_execz BB3_2 @@ -125,8 +125,8 @@ exit: ; SI: BB3_3: ; SI: buffer_load_dword [[B:v[0-9]+]] ; SI: buffer_load_dword [[A:v[0-9]+]] -; SI-DAG: v_cmp_ne_i32_e64 [[NEG1_CHECK_0:s\[[0-9]+:[0-9]+\]]], [[A]], -1 -; SI-DAG: v_cmp_ne_i32_e64 [[NEG1_CHECK_1:s\[[0-9]+:[0-9]+\]]], [[B]], -1 +; SI-DAG: v_cmp_ne_i32_e64 [[NEG1_CHECK_0:s\[[0-9]+:[0-9]+\]]], -1, [[A]] +; SI-DAG: v_cmp_ne_i32_e32 [[NEG1_CHECK_1:vcc]], -1, [[B]] ; SI: s_and_b64 [[ORNEG1:s\[[0-9]+:[0-9]+\]]], [[NEG1_CHECK_1]], [[NEG1_CHECK_0]] ; SI: s_and_saveexec_b64 [[ORNEG1]], [[ORNEG1]] ; SI: s_xor_b64 [[ORNEG1]], exec, [[ORNEG1]] diff --git a/llvm/test/CodeGen/R600/xor.ll b/llvm/test/CodeGen/R600/xor.ll index ea78cca38e9e..089db59eabc7 100644 --- a/llvm/test/CodeGen/R600/xor.ll +++ b/llvm/test/CodeGen/R600/xor.ll @@ -40,8 +40,8 @@ define void @xor_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in ; FUNC-LABEL: {{^}}xor_i1: ; EG: XOR_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW], PS}} -; SI-DAG: v_cmp_ge_f32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], {{v[0-9]+}}, 0 -; SI-DAG: v_cmp_ge_f32_e64 [[CMP1:s\[[0-9]+:[0-9]+\]]], {{v[0-9]+}}, 1.0 +; SI-DAG: v_cmp_le_f32_e32 [[CMP0:vcc]], 0, {{v[0-9]+}} +; SI-DAG: v_cmp_le_f32_e64 [[CMP1:s\[[0-9]+:[0-9]+\]]], 1.0, {{v[0-9]+}} ; SI: s_xor_b64 [[XOR:s\[[0-9]+:[0-9]+\]]], [[CMP0]], [[CMP1]] ; SI: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], {{v[0-9]+}}, {{v[0-9]+}}, [[XOR]] ; SI: buffer_store_dword [[RESULT]]