From 0f3982734058d9039d986e9d1dd3a879ff3512f0 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 22 Nov 2013 23:07:58 +0000 Subject: [PATCH] R600/SI: Fixing handling of condition codes We were ignoring the ordered/onordered bits and also the signed/unsigned bits of condition codes when lowering the DAG to MachineInstrs. NOTE: This is a candidate for the 3.4 branch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195514 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/AMDGPUInstructions.td | 75 +++--- lib/Target/R600/R600Instructions.td | 6 +- lib/Target/R600/SIISelLowering.cpp | 15 ++ lib/Target/R600/SIInstructions.td | 78 +++---- test/CodeGen/R600/setcc.ll | 323 +++++++++++++++++++++++++- test/CodeGen/R600/setcc64.ll | 263 +++++++++++++++++++++ 6 files changed, 675 insertions(+), 85 deletions(-) create mode 100644 test/CodeGen/R600/setcc64.ll diff --git a/lib/Target/R600/AMDGPUInstructions.td b/lib/Target/R600/AMDGPUInstructions.td index 3e1fc27e12d..3c5375d84ec 100644 --- a/lib/Target/R600/AMDGPUInstructions.td +++ b/lib/Target/R600/AMDGPUInstructions.td @@ -37,66 +37,73 @@ class AMDGPUShaderInst pattern> def InstFlag : OperandWithDefaultOps ; def ADDRIndirect : ComplexPattern; -def COND_EQ : PatLeaf < - (cond), - [{switch(N->get()){{default: return false; - case ISD::SETOEQ: case ISD::SETUEQ: - case ISD::SETEQ: return true;}}}] ->; +//===----------------------------------------------------------------------===// +// PatLeafs for floating-point comparisons +//===----------------------------------------------------------------------===// def COND_OEQ : PatLeaf < (cond), [{return N->get() == ISD::SETOEQ || N->get() == ISD::SETEQ;}] >; -def COND_NE : PatLeaf < +def COND_OGT : PatLeaf < (cond), - [{switch(N->get()){{default: return false; - case ISD::SETONE: case ISD::SETUNE: - case ISD::SETNE: return true;}}}] + [{return N->get() == ISD::SETOGT || N->get() == ISD::SETGT;}] >; -def COND_UNE : PatLeaf < +def COND_OGE : PatLeaf < (cond), - [{return N->get() == ISD::SETUNE || N->get() == ISD::SETNE;}] + [{return N->get() == ISD::SETOGE || N->get() == ISD::SETGE;}] >; -def COND_GT : PatLeaf < +def COND_OLT : PatLeaf < (cond), - [{switch(N->get()){{default: return false; - case ISD::SETOGT: case ISD::SETUGT: - case ISD::SETGT: return true;}}}] + [{return N->get() == ISD::SETOLT || N->get() == ISD::SETLT;}] >; -def COND_OGT : PatLeaf < +def COND_OLE : PatLeaf < (cond), - [{return N->get() == ISD::SETOGT || N->get() == ISD::SETGT;}] + [{return N->get() == ISD::SETOLE || N->get() == ISD::SETLE;}] >; -def COND_GE : PatLeaf < +def COND_UNE : PatLeaf < (cond), - [{switch(N->get()){{default: return false; - case ISD::SETOGE: case ISD::SETUGE: - case ISD::SETGE: return true;}}}] + [{return N->get() == ISD::SETUNE || N->get() == ISD::SETNE;}] >; -def COND_OGE : PatLeaf < - (cond), - [{return N->get() == ISD::SETOGE || N->get() == ISD::SETGE;}] ->; +def COND_O : PatLeaf <(cond), [{return N->get() == ISD::SETO;}]>; +def COND_UO : PatLeaf <(cond), [{return N->get() == ISD::SETUO;}]>; + +//===----------------------------------------------------------------------===// +// PatLeafs for unsigned comparisons +//===----------------------------------------------------------------------===// + +def COND_UGT : PatLeaf <(cond), [{return N->get() == ISD::SETUGT;}]>; +def COND_UGE : PatLeaf <(cond), [{return N->get() == ISD::SETUGE;}]>; +def COND_ULT : PatLeaf <(cond), [{return N->get() == ISD::SETULT;}]>; +def COND_ULE : PatLeaf <(cond), [{return N->get() == ISD::SETULE;}]>; + +//===----------------------------------------------------------------------===// +// PatLeafs for signed comparisons +//===----------------------------------------------------------------------===// + +def COND_SGT : PatLeaf <(cond), [{return N->get() == ISD::SETGT;}]>; +def COND_SGE : PatLeaf <(cond), [{return N->get() == ISD::SETGE;}]>; +def COND_SLT : PatLeaf <(cond), [{return N->get() == ISD::SETLT;}]>; +def COND_SLE : PatLeaf <(cond), [{return N->get() == ISD::SETLE;}]>; + +//===----------------------------------------------------------------------===// +// PatLeafs for integer equality +//===----------------------------------------------------------------------===// -def COND_LT : PatLeaf < +def COND_EQ : PatLeaf < (cond), - [{switch(N->get()){{default: return false; - case ISD::SETOLT: case ISD::SETULT: - case ISD::SETLT: return true;}}}] + [{return N->get() == ISD::SETEQ || N->get() == ISD::SETUEQ;}] >; -def COND_LE : PatLeaf < +def COND_NE : PatLeaf < (cond), - [{switch(N->get()){{default: return false; - case ISD::SETOLE: case ISD::SETULE: - case ISD::SETLE: return true;}}}] + [{return N->get() == ISD::SETNE || N->get() == ISD::SETUNE;}] >; def COND_NULL : PatLeaf < diff --git a/lib/Target/R600/R600Instructions.td b/lib/Target/R600/R600Instructions.td index d8e431a8cd6..abfde501735 100644 --- a/lib/Target/R600/R600Instructions.td +++ b/lib/Target/R600/R600Instructions.td @@ -822,12 +822,12 @@ def CNDE_INT : R600_3OP < def CNDGE_INT : R600_3OP < 0x1E, "CNDGE_INT", - [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_GE))] + [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_SGE))] >; def CNDGT_INT : R600_3OP < 0x1D, "CNDGT_INT", - [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_GT))] + [(set i32:$dst, (selectcc i32:$src0, 0, i32:$src1, i32:$src2, COND_SGT))] >; //===----------------------------------------------------------------------===// @@ -2313,7 +2313,7 @@ def : CND_INT_f32 ; //CNDGE_INT extra pattern def : Pat < - (selectcc i32:$src0, -1, i32:$src1, i32:$src2, COND_GT), + (selectcc i32:$src0, -1, i32:$src1, i32:$src2, COND_SGT), (CNDGE_INT $src0, $src1, $src2) >; diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp index 9435e9b4fc3..d5d2b68caf0 100644 --- a/lib/Target/R600/SIISelLowering.cpp +++ b/lib/Target/R600/SIISelLowering.cpp @@ -56,6 +56,21 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) : computeRegisterProperties(); + // Condition Codes + setCondCodeAction(ISD::SETONE, MVT::f32, Expand); + setCondCodeAction(ISD::SETUEQ, MVT::f32, Expand); + setCondCodeAction(ISD::SETUGE, MVT::f32, Expand); + setCondCodeAction(ISD::SETUGT, MVT::f32, Expand); + setCondCodeAction(ISD::SETULE, MVT::f32, Expand); + setCondCodeAction(ISD::SETULT, MVT::f32, Expand); + + setCondCodeAction(ISD::SETONE, MVT::f64, Expand); + setCondCodeAction(ISD::SETUEQ, MVT::f64, Expand); + setCondCodeAction(ISD::SETUGE, MVT::f64, Expand); + setCondCodeAction(ISD::SETUGT, MVT::f64, Expand); + setCondCodeAction(ISD::SETULE, MVT::f64, Expand); + setCondCodeAction(ISD::SETULT, MVT::f64, Expand); + setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v8i32, Expand); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v8f32, Expand); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v16i32, Expand); diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 855e1a99985..7827a9ac624 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -143,19 +143,19 @@ def S_GETREG_REGRD_B32 : SOPK_32 <0x00000014, "S_GETREG_REGRD_B32", []>; let isCompare = 1 in { defm V_CMP_F_F32 : VOPC_32 <0x00000000, "V_CMP_F_F32">; -defm V_CMP_LT_F32 : VOPC_32 <0x00000001, "V_CMP_LT_F32", f32, COND_LT>; -defm V_CMP_EQ_F32 : VOPC_32 <0x00000002, "V_CMP_EQ_F32", f32, COND_EQ>; -defm V_CMP_LE_F32 : VOPC_32 <0x00000003, "V_CMP_LE_F32", f32, COND_LE>; -defm V_CMP_GT_F32 : VOPC_32 <0x00000004, "V_CMP_GT_F32", f32, COND_GT>; -defm V_CMP_LG_F32 : VOPC_32 <0x00000005, "V_CMP_LG_F32", f32, COND_NE>; -defm V_CMP_GE_F32 : VOPC_32 <0x00000006, "V_CMP_GE_F32", f32, COND_GE>; -defm V_CMP_O_F32 : VOPC_32 <0x00000007, "V_CMP_O_F32">; -defm V_CMP_U_F32 : VOPC_32 <0x00000008, "V_CMP_U_F32">; +defm V_CMP_LT_F32 : VOPC_32 <0x00000001, "V_CMP_LT_F32", f32, COND_OLT>; +defm V_CMP_EQ_F32 : VOPC_32 <0x00000002, "V_CMP_EQ_F32", f32, COND_OEQ>; +defm V_CMP_LE_F32 : VOPC_32 <0x00000003, "V_CMP_LE_F32", f32, COND_OLE>; +defm V_CMP_GT_F32 : VOPC_32 <0x00000004, "V_CMP_GT_F32", f32, COND_OGT>; +defm V_CMP_LG_F32 : VOPC_32 <0x00000005, "V_CMP_LG_F32">; +defm V_CMP_GE_F32 : VOPC_32 <0x00000006, "V_CMP_GE_F32", f32, COND_OGE>; +defm V_CMP_O_F32 : VOPC_32 <0x00000007, "V_CMP_O_F32", f32, COND_O>; +defm V_CMP_U_F32 : VOPC_32 <0x00000008, "V_CMP_U_F32", f32, COND_UO>; defm V_CMP_NGE_F32 : VOPC_32 <0x00000009, "V_CMP_NGE_F32">; defm V_CMP_NLG_F32 : VOPC_32 <0x0000000a, "V_CMP_NLG_F32">; defm V_CMP_NGT_F32 : VOPC_32 <0x0000000b, "V_CMP_NGT_F32">; defm V_CMP_NLE_F32 : VOPC_32 <0x0000000c, "V_CMP_NLE_F32">; -defm V_CMP_NEQ_F32 : VOPC_32 <0x0000000d, "V_CMP_NEQ_F32", f32, COND_NE>; +defm V_CMP_NEQ_F32 : VOPC_32 <0x0000000d, "V_CMP_NEQ_F32", f32, COND_UNE>; defm V_CMP_NLT_F32 : VOPC_32 <0x0000000e, "V_CMP_NLT_F32">; defm V_CMP_TRU_F32 : VOPC_32 <0x0000000f, "V_CMP_TRU_F32">; @@ -181,19 +181,19 @@ defm V_CMPX_TRU_F32 : VOPC_32 <0x0000001f, "V_CMPX_TRU_F32">; } // End hasSideEffects = 1, Defs = [EXEC] defm V_CMP_F_F64 : VOPC_64 <0x00000020, "V_CMP_F_F64">; -defm V_CMP_LT_F64 : VOPC_64 <0x00000021, "V_CMP_LT_F64", f64, COND_LT>; -defm V_CMP_EQ_F64 : VOPC_64 <0x00000022, "V_CMP_EQ_F64", f64, COND_EQ>; -defm V_CMP_LE_F64 : VOPC_64 <0x00000023, "V_CMP_LE_F64", f64, COND_LE>; -defm V_CMP_GT_F64 : VOPC_64 <0x00000024, "V_CMP_GT_F64", f64, COND_GT>; +defm V_CMP_LT_F64 : VOPC_64 <0x00000021, "V_CMP_LT_F64", f64, COND_OLT>; +defm V_CMP_EQ_F64 : VOPC_64 <0x00000022, "V_CMP_EQ_F64", f64, COND_OEQ>; +defm V_CMP_LE_F64 : VOPC_64 <0x00000023, "V_CMP_LE_F64", f64, COND_OLE>; +defm V_CMP_GT_F64 : VOPC_64 <0x00000024, "V_CMP_GT_F64", f64, COND_OGT>; defm V_CMP_LG_F64 : VOPC_64 <0x00000025, "V_CMP_LG_F64">; -defm V_CMP_GE_F64 : VOPC_64 <0x00000026, "V_CMP_GE_F64", f64, COND_GE>; -defm V_CMP_O_F64 : VOPC_64 <0x00000027, "V_CMP_O_F64">; -defm V_CMP_U_F64 : VOPC_64 <0x00000028, "V_CMP_U_F64">; +defm V_CMP_GE_F64 : VOPC_64 <0x00000026, "V_CMP_GE_F64", f64, COND_OGE>; +defm V_CMP_O_F64 : VOPC_64 <0x00000027, "V_CMP_O_F64", f64, COND_O>; +defm V_CMP_U_F64 : VOPC_64 <0x00000028, "V_CMP_U_F64", f64, COND_UO>; defm V_CMP_NGE_F64 : VOPC_64 <0x00000029, "V_CMP_NGE_F64">; defm V_CMP_NLG_F64 : VOPC_64 <0x0000002a, "V_CMP_NLG_F64">; defm V_CMP_NGT_F64 : VOPC_64 <0x0000002b, "V_CMP_NGT_F64">; defm V_CMP_NLE_F64 : VOPC_64 <0x0000002c, "V_CMP_NLE_F64">; -defm V_CMP_NEQ_F64 : VOPC_64 <0x0000002d, "V_CMP_NEQ_F64", f64, COND_NE>; +defm V_CMP_NEQ_F64 : VOPC_64 <0x0000002d, "V_CMP_NEQ_F64", f64, COND_UNE>; defm V_CMP_NLT_F64 : VOPC_64 <0x0000002e, "V_CMP_NLT_F64">; defm V_CMP_TRU_F64 : VOPC_64 <0x0000002f, "V_CMP_TRU_F64">; @@ -295,12 +295,12 @@ defm V_CMPSX_TRU_F64 : VOPC_64 <0x0000007f, "V_CMPSX_TRU_F64">; } // End hasSideEffects = 1, Defs = [EXEC] defm V_CMP_F_I32 : VOPC_32 <0x00000080, "V_CMP_F_I32">; -defm V_CMP_LT_I32 : VOPC_32 <0x00000081, "V_CMP_LT_I32", i32, COND_LT>; +defm V_CMP_LT_I32 : VOPC_32 <0x00000081, "V_CMP_LT_I32", i32, COND_SLT>; defm V_CMP_EQ_I32 : VOPC_32 <0x00000082, "V_CMP_EQ_I32", i32, COND_EQ>; -defm V_CMP_LE_I32 : VOPC_32 <0x00000083, "V_CMP_LE_I32", i32, COND_LE>; -defm V_CMP_GT_I32 : VOPC_32 <0x00000084, "V_CMP_GT_I32", i32, COND_GT>; +defm V_CMP_LE_I32 : VOPC_32 <0x00000083, "V_CMP_LE_I32", i32, COND_SLE>; +defm V_CMP_GT_I32 : VOPC_32 <0x00000084, "V_CMP_GT_I32", i32, COND_SGT>; defm V_CMP_NE_I32 : VOPC_32 <0x00000085, "V_CMP_NE_I32", i32, COND_NE>; -defm V_CMP_GE_I32 : VOPC_32 <0x00000086, "V_CMP_GE_I32", i32, COND_GE>; +defm V_CMP_GE_I32 : VOPC_32 <0x00000086, "V_CMP_GE_I32", i32, COND_SGE>; defm V_CMP_T_I32 : VOPC_32 <0x00000087, "V_CMP_T_I32">; let hasSideEffects = 1, Defs = [EXEC] in { @@ -317,12 +317,12 @@ defm V_CMPX_T_I32 : VOPC_32 <0x00000097, "V_CMPX_T_I32">; } // End hasSideEffects = 1, Defs = [EXEC] defm V_CMP_F_I64 : VOPC_64 <0x000000a0, "V_CMP_F_I64">; -defm V_CMP_LT_I64 : VOPC_64 <0x000000a1, "V_CMP_LT_I64">; -defm V_CMP_EQ_I64 : VOPC_64 <0x000000a2, "V_CMP_EQ_I64">; -defm V_CMP_LE_I64 : VOPC_64 <0x000000a3, "V_CMP_LE_I64">; -defm V_CMP_GT_I64 : VOPC_64 <0x000000a4, "V_CMP_GT_I64">; -defm V_CMP_NE_I64 : VOPC_64 <0x000000a5, "V_CMP_NE_I64">; -defm V_CMP_GE_I64 : VOPC_64 <0x000000a6, "V_CMP_GE_I64">; +defm V_CMP_LT_I64 : VOPC_64 <0x000000a1, "V_CMP_LT_I64", i64, COND_SLT>; +defm V_CMP_EQ_I64 : VOPC_64 <0x000000a2, "V_CMP_EQ_I64", i64, COND_EQ>; +defm V_CMP_LE_I64 : VOPC_64 <0x000000a3, "V_CMP_LE_I64", i64, COND_SLE>; +defm V_CMP_GT_I64 : VOPC_64 <0x000000a4, "V_CMP_GT_I64", i64, COND_SGT>; +defm V_CMP_NE_I64 : VOPC_64 <0x000000a5, "V_CMP_NE_I64", i64, COND_NE>; +defm V_CMP_GE_I64 : VOPC_64 <0x000000a6, "V_CMP_GE_I64", i64, COND_SGE>; defm V_CMP_T_I64 : VOPC_64 <0x000000a7, "V_CMP_T_I64">; let hasSideEffects = 1, Defs = [EXEC] in { @@ -339,12 +339,12 @@ defm V_CMPX_T_I64 : VOPC_64 <0x000000b7, "V_CMPX_T_I64">; } // End hasSideEffects = 1, Defs = [EXEC] defm V_CMP_F_U32 : VOPC_32 <0x000000c0, "V_CMP_F_U32">; -defm V_CMP_LT_U32 : VOPC_32 <0x000000c1, "V_CMP_LT_U32">; -defm V_CMP_EQ_U32 : VOPC_32 <0x000000c2, "V_CMP_EQ_U32">; -defm V_CMP_LE_U32 : VOPC_32 <0x000000c3, "V_CMP_LE_U32">; -defm V_CMP_GT_U32 : VOPC_32 <0x000000c4, "V_CMP_GT_U32">; -defm V_CMP_NE_U32 : VOPC_32 <0x000000c5, "V_CMP_NE_U32">; -defm V_CMP_GE_U32 : VOPC_32 <0x000000c6, "V_CMP_GE_U32">; +defm V_CMP_LT_U32 : VOPC_32 <0x000000c1, "V_CMP_LT_U32", i32, COND_ULT>; +defm V_CMP_EQ_U32 : VOPC_32 <0x000000c2, "V_CMP_EQ_U32", i32, COND_EQ>; +defm V_CMP_LE_U32 : VOPC_32 <0x000000c3, "V_CMP_LE_U32", i32, COND_ULE>; +defm V_CMP_GT_U32 : VOPC_32 <0x000000c4, "V_CMP_GT_U32", i32, COND_UGT>; +defm V_CMP_NE_U32 : VOPC_32 <0x000000c5, "V_CMP_NE_U32", i32, COND_NE>; +defm V_CMP_GE_U32 : VOPC_32 <0x000000c6, "V_CMP_GE_U32", i32, COND_UGE>; defm V_CMP_T_U32 : VOPC_32 <0x000000c7, "V_CMP_T_U32">; let hasSideEffects = 1, Defs = [EXEC] in { @@ -361,12 +361,12 @@ defm V_CMPX_T_U32 : VOPC_32 <0x000000d7, "V_CMPX_T_U32">; } // End hasSideEffects = 1, Defs = [EXEC] defm V_CMP_F_U64 : VOPC_64 <0x000000e0, "V_CMP_F_U64">; -defm V_CMP_LT_U64 : VOPC_64 <0x000000e1, "V_CMP_LT_U64">; -defm V_CMP_EQ_U64 : VOPC_64 <0x000000e2, "V_CMP_EQ_U64">; -defm V_CMP_LE_U64 : VOPC_64 <0x000000e3, "V_CMP_LE_U64">; -defm V_CMP_GT_U64 : VOPC_64 <0x000000e4, "V_CMP_GT_U64">; -defm V_CMP_NE_U64 : VOPC_64 <0x000000e5, "V_CMP_NE_U64">; -defm V_CMP_GE_U64 : VOPC_64 <0x000000e6, "V_CMP_GE_U64">; +defm V_CMP_LT_U64 : VOPC_64 <0x000000e1, "V_CMP_LT_U64", i64, COND_ULT>; +defm V_CMP_EQ_U64 : VOPC_64 <0x000000e2, "V_CMP_EQ_U64", i64, COND_EQ>; +defm V_CMP_LE_U64 : VOPC_64 <0x000000e3, "V_CMP_LE_U64", i64, COND_ULE>; +defm V_CMP_GT_U64 : VOPC_64 <0x000000e4, "V_CMP_GT_U64", i64, COND_UGT>; +defm V_CMP_NE_U64 : VOPC_64 <0x000000e5, "V_CMP_NE_U64", i64, COND_NE>; +defm V_CMP_GE_U64 : VOPC_64 <0x000000e6, "V_CMP_GE_U64", i64, COND_UGE>; defm V_CMP_T_U64 : VOPC_64 <0x000000e7, "V_CMP_T_U64">; let hasSideEffects = 1, Defs = [EXEC] in { diff --git a/test/CodeGen/R600/setcc.ll b/test/CodeGen/R600/setcc.ll index 1ca216c483f..8d34c4ad4fe 100644 --- a/test/CodeGen/R600/setcc.ll +++ b/test/CodeGen/R600/setcc.ll @@ -1,8 +1,9 @@ -;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck --check-prefix=EG-CHECK %s +;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck --check-prefix=R600 --check-prefix=FUNC %s +;RUN: llc < %s -march=r600 -mcpu=SI | FileCheck --check-prefix=SI --check-prefix=FUNC %s -; CHECK: @setcc_v2i32 -; EG-CHECK-DAG: SETE_INT * T{{[0-9]+\.[XYZW]}}, KC0[3].X, KC0[3].Z -; EG-CHECK-DAG: SETE_INT * T{{[0-9]+\.[XYZW]}}, KC0[2].W, KC0[3].Y +; FUNC-LABEL: @setcc_v2i32 +; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW]}}, KC0[3].X, KC0[3].Z +; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW]}}, KC0[2].W, KC0[3].Y define void @setcc_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) { %result = icmp eq <2 x i32> %a, %b @@ -11,11 +12,11 @@ define void @setcc_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> % ret void } -; CHECK: @setcc_v4i32 -; EG-CHECK-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG-CHECK-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG-CHECK-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} -; EG-CHECK-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; FUNC-LABEL: @setcc_v4i32 +; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} +; R600-DAG: SETE_INT * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}} define void @setcc_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) { %b_ptr = getelementptr <4 x i32> addrspace(1)* %in, i32 1 @@ -26,3 +27,307 @@ define void @setcc_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* % store <4 x i32> %sext, <4 x i32> addrspace(1)* %out ret void } + +;;;==========================================================================;;; +;; Float comparisons +;;;==========================================================================;;; + +; FUNC-LABEL: @f32_oeq +; R600: SETE_DX10 +; SI: V_CMP_EQ_F32 +define void @f32_oeq(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp oeq float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_ogt +; R600: SETGT_DX10 +; SI: V_CMP_GT_F32 +define void @f32_ogt(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp ogt float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_oge +; R600: SETGE_DX10 +; SI: V_CMP_GE_F32 +define void @f32_oge(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp oge float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_olt +; R600: SETGT_DX10 +; SI: V_CMP_LT_F32 +define void @f32_olt(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp olt float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_ole +; R600: SETGE_DX10 +; SI: V_CMP_LE_F32 +define void @f32_ole(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp ole float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_one +; R600-DAG: SETE_DX10 +; R600-DAG: SETE_DX10 +; R600-DAG: AND_INT +; R600-DAG: SETNE_DX10 +; R600-DAG: AND_INT +; R600-DAG: SETNE_INT +; SI: V_CMP_O_F32 +; SI: V_CMP_NEQ_F32 +; SI: S_AND_B64 +define void @f32_one(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp one float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_ord +; R600-DAG: SETE_DX10 +; R600-DAG: SETE_DX10 +; R600-DAG: AND_INT +; R600-DAG: SETNE_INT +; SI: V_CMP_O_F32 +define void @f32_ord(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp ord float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_ueq +; R600-DAG: SETNE_DX10 +; R600-DAG: SETNE_DX10 +; R600-DAG: OR_INT +; R600-DAG: SETE_DX10 +; R600-DAG: OR_INT +; R600-DAG: SETNE_INT +; SI: V_CMP_U_F32 +; SI: V_CMP_EQ_F32 +; SI: S_OR_B64 +define void @f32_ueq(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp ueq float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_ugt +; R600: SETGE +; R600: SETE_DX10 +; SI: V_CMP_U_F32 +; SI: V_CMP_GT_F32 +; SI: S_OR_B64 +define void @f32_ugt(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp ugt float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_uge +; R600: SETGT +; R600: SETE_DX10 +; SI: V_CMP_U_F32 +; SI: V_CMP_GE_F32 +; SI: S_OR_B64 +define void @f32_uge(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp uge float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_ult +; R600: SETGE +; R600: SETE_DX10 +; SI: V_CMP_U_F32 +; SI: V_CMP_LT_F32 +; SI: S_OR_B64 +define void @f32_ult(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp ult float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_ule +; R600: SETGT +; R600: SETE_DX10 +; SI: V_CMP_U_F32 +; SI: V_CMP_LE_F32 +; SI: S_OR_B64 +define void @f32_ule(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp ule float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_une +; R600: SETNE_DX10 +; SI: V_CMP_NEQ_F32 +define void @f32_une(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp une float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f32_uno +; R600: SETNE_DX10 +; R600: SETNE_DX10 +; R600: OR_INT +; R600: SETNE_INT +; SI: V_CMP_U_F32 +define void @f32_uno(i32 addrspace(1)* %out, float %a, float %b) { +entry: + %0 = fcmp uno float %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +;;;==========================================================================;;; +;; 32-bit integer comparisons +;;;==========================================================================;;; + +; FUNC-LABEL: @i32_eq +; R600: SETE_INT +; SI: V_CMP_EQ_I32 +define void @i32_eq(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp eq i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_ne +; R600: SETNE_INT +; SI: V_CMP_NE_I32 +define void @i32_ne(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp ne i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_ugt +; R600: SETGT_UINT +; SI: V_CMP_GT_U32 +define void @i32_ugt(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp ugt i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_uge +; R600: SETGE_UINT +; SI: V_CMP_GE_U32 +define void @i32_uge(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp uge i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_ult +; R600: SETGT_UINT +; SI: V_CMP_LT_U32 +define void @i32_ult(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp ult i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_ule +; R600: SETGE_UINT +; SI: V_CMP_LE_U32 +define void @i32_ule(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp ule i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_sgt +; R600: SETGT_INT +; SI: V_CMP_GT_I32 +define void @i32_sgt(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp sgt i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_sge +; R600: SETGE_INT +; SI: V_CMP_GE_I32 +define void @i32_sge(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp sge i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_slt +; R600: SETGT_INT +; SI: V_CMP_LT_I32 +define void @i32_slt(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp slt i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i32_sle +; R600: SETGE_INT +; SI: V_CMP_LE_I32 +define void @i32_sle(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp sle i32 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/setcc64.ll b/test/CodeGen/R600/setcc64.ll new file mode 100644 index 00000000000..9202fc01f55 --- /dev/null +++ b/test/CodeGen/R600/setcc64.ll @@ -0,0 +1,263 @@ +;RUN: llc < %s -march=r600 -mcpu=SI | FileCheck --check-prefix=SI --check-prefix=FUNC %s + +; XXX: Merge this into setcc, once R600 supports 64-bit operations + +;;;==========================================================================;;; +;; Double comparisons +;;;==========================================================================;;; + +; FUNC-LABEL: @f64_oeq +; SI: V_CMP_EQ_F64 +define void @f64_oeq(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp oeq double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_ogt +; SI: V_CMP_GT_F64 +define void @f64_ogt(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp ogt double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_oge +; SI: V_CMP_GE_F64 +define void @f64_oge(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp oge double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_olt +; SI: V_CMP_LT_F64 +define void @f64_olt(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp olt double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_ole +; SI: V_CMP_LE_F64 +define void @f64_ole(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp ole double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_one +; SI: V_CMP_O_F64 +; SI: V_CMP_NEQ_F64 +; SI: S_AND_B64 +define void @f64_one(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp one double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_ord +; SI: V_CMP_O_F64 +define void @f64_ord(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp ord double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_ueq +; SI: V_CMP_U_F64 +; SI: V_CMP_EQ_F64 +; SI: S_OR_B64 +define void @f64_ueq(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp ueq double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_ugt +; SI: V_CMP_U_F64 +; SI: V_CMP_GT_F64 +; SI: S_OR_B64 +define void @f64_ugt(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp ugt double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_uge +; SI: V_CMP_U_F64 +; SI: V_CMP_GE_F64 +; SI: S_OR_B64 +define void @f64_uge(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp uge double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_ult +; SI: V_CMP_U_F64 +; SI: V_CMP_LT_F64 +; SI: S_OR_B64 +define void @f64_ult(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp ult double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_ule +; SI: V_CMP_U_F64 +; SI: V_CMP_LE_F64 +; SI: S_OR_B64 +define void @f64_ule(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp ule double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_une +; SI: V_CMP_NEQ_F64 +define void @f64_une(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp une double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @f64_uno +; SI: V_CMP_U_F64 +define void @f64_uno(i32 addrspace(1)* %out, double %a, double %b) { +entry: + %0 = fcmp uno double %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +;;;==========================================================================;;; +;; 64-bit integer comparisons +;;;==========================================================================;;; + +; FUNC-LABEL: @i64_eq +; SI: V_CMP_EQ_I64 +define void @i64_eq(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp eq i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_ne +; SI: V_CMP_NE_I64 +define void @i64_ne(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp ne i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_ugt +; SI: V_CMP_GT_U64 +define void @i64_ugt(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp ugt i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_uge +; SI: V_CMP_GE_U64 +define void @i64_uge(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp uge i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_ult +; SI: V_CMP_LT_U64 +define void @i64_ult(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp ult i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_ule +; SI: V_CMP_LE_U64 +define void @i64_ule(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp ule i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_sgt +; SI: V_CMP_GT_I64 +define void @i64_sgt(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp sgt i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_sge +; SI: V_CMP_GE_I64 +define void @i64_sge(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp sge i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_slt +; SI: V_CMP_LT_I64 +define void @i64_slt(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp slt i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; FUNC-LABEL: @i64_sle +; SI: V_CMP_LE_I64 +define void @i64_sle(i32 addrspace(1)* %out, i64 %a, i64 %b) { +entry: + %0 = icmp sle i64 %a, %b + %1 = sext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} -- 2.34.1