Index: include/llvm/CodeGen/GlobalISel/InstructionSelector.h =================================================================== --- include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -208,6 +208,12 @@ /// - Expected Intrinsic ID GIM_CheckIntrinsicID, + /// Check the operand is a specific predicate + /// - InsnID - Instruction ID + /// - OpIdx - Operand index + /// - Expected predicate + GIM_CheckCmpPredicate, + /// Check the specified operand is an MBB /// - InsnID - Instruction ID /// - OpIdx - Operand index Index: include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h =================================================================== --- include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -662,7 +662,21 @@ return false; break; } - + case GIM_CheckCmpPredicate: { + int64_t InsnID = MatchTable[CurrentIdx++]; + int64_t OpIdx = MatchTable[CurrentIdx++]; + int64_t Value = MatchTable[CurrentIdx++]; + DEBUG_WITH_TYPE(TgtInstructionSelector::getName(), + dbgs() << CurrentIdx << ": GIM_CheckCmpPredicate(MIs[" + << InsnID << "]->getOperand(" << OpIdx + << "), Value=" << Value << ")\n"); + assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); + MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx); + if (!MO.isPredicate() || MO.getPredicate() != Value) + if (handleReject() == RejectAndGiveUp) + return false; + break; + } case GIM_CheckIsMBB: { int64_t InsnID = MatchTable[CurrentIdx++]; int64_t OpIdx = MatchTable[CurrentIdx++]; Index: include/llvm/Target/GlobalISel/SelectionDAGCompat.td =================================================================== --- include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -109,6 +109,8 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some // complications that tablegen must take care of. For example, Predicates such Index: lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp +++ lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp @@ -163,11 +163,10 @@ const RegisterBank &AMDGPURegisterBankInfo::getRegBankFromRegClass( const TargetRegisterClass &RC) const { + if (&RC == &AMDGPU::SReg_1RegClass) + return AMDGPU::VCCRegBank; - if (TRI->isSGPRClass(&RC)) - return getRegBank(AMDGPU::SGPRRegBankID); - - return getRegBank(AMDGPU::VGPRRegBankID); + return TRI->isSGPRClass(&RC) ? AMDGPU::SGPRRegBank : AMDGPU::VGPRRegBank; } template Index: lib/Target/AMDGPU/AMDGPURegisterBanks.td =================================================================== --- lib/Target/AMDGPU/AMDGPURegisterBanks.td +++ lib/Target/AMDGPU/AMDGPURegisterBanks.td @@ -17,4 +17,4 @@ def SCCRegBank : RegisterBank <"SCC", [SReg_32, SCC_CLASS]>; // It is helpful to distinguish conditions from ordinary SGPRs. -def VCCRegBank : RegisterBank <"VCC", [SReg_64]>; +def VCCRegBank : RegisterBank <"VCC", [SReg_1]>; Index: test/CodeGen/AMDGPU/GlobalISel/inst-select-fcmp.mir =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/GlobalISel/inst-select-fcmp.mir @@ -0,0 +1,799 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -mcpu=tahiti -run-pass=instruction-select -verify-machineinstrs -global-isel-abort=0 -o - %s | FileCheck -check-prefix=WAVE64 %s +# RUN: llc -march=amdgcn -mcpu=gfx1010 -run-pass=instruction-select -verify-machineinstrs -global-isel-abort=0 -o - %s | FileCheck -check-prefix=WAVE32 %s + +--- +name: fcmp_false_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_false_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE64: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(false), [[COPY]](s32), [[COPY1]] + ; WAVE64: S_ENDPGM 0, implicit [[FCMP]](s1) + ; WAVE32-LABEL: name: fcmp_false_s32_vv + ; WAVE32: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE32: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(false), [[COPY]](s32), [[COPY1]] + ; WAVE32: S_ENDPGM 0, implicit [[FCMP]](s1) + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(false), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_oeq_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_oeq_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_EQ_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_EQ_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_oeq_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_EQ_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_EQ_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_EQ_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(oeq), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ogt_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ogt_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_GT_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_GT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_GT_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_ogt_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_GT_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_GT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_GT_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(ogt), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_oge_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_oge_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_GE_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_GE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_GE_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_oge_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_GE_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_GE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_GE_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(oge), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_olt_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_olt_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_LT_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_LT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LT_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_olt_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_LT_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LT_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(olt), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ole_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ole_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_LE_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_LE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LE_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_ole_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_LE_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LE_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(ole), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_one_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_one_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_LG_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_LG_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LG_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_one_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_LG_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LG_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LG_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(one), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ord_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ord_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_O_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_O_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_O_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_ord_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_O_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_O_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_O_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(ord), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_uno_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_uno_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_U_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_U_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_U_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_uno_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_U_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_U_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_U_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(uno), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ueq_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ueq_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NLG_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLG_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLG_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_ueq_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NLG_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLG_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLG_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(ueq), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ugt_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ugt_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NLE_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLE_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_ugt_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NLE_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLE_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(ugt), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_uge_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_uge_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NLT_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLT_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_uge_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NLT_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLT_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(uge), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ult_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ult_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NGE_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_NGE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NGE_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_ult_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NGE_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NGE_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NGE_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(ult), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ule_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ule_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NGT_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_NGT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NGT_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_ule_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NGT_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NGT_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NGT_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(ule), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_une_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_une_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NEQ_F32_e64_:%[0-9]+]]:sreg_64 = V_CMP_NEQ_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NEQ_F32_e64_]] + ; WAVE32-LABEL: name: fcmp_une_s32_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NEQ_F32_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NEQ_F32_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NEQ_F32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(une), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_true_s32_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_true_s32_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE64: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(true), [[COPY]](s32), [[COPY1]] + ; WAVE64: S_ENDPGM 0, implicit [[FCMP]](s1) + ; WAVE32-LABEL: name: fcmp_true_s32_vv + ; WAVE32: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE32: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(true), [[COPY]](s32), [[COPY1]] + ; WAVE32: S_ENDPGM 0, implicit [[FCMP]](s1) + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vcc(s1) = G_FCMP floatpred(true), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_false_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_false_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr(s64) = COPY $vgpr2_vgpr3 + ; WAVE64: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(false), [[COPY]](s64), [[COPY1]] + ; WAVE64: S_ENDPGM 0, implicit [[FCMP]](s1) + ; WAVE32-LABEL: name: fcmp_false_s64_vv + ; WAVE32: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr(s64) = COPY $vgpr2_vgpr3 + ; WAVE32: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(false), [[COPY]](s64), [[COPY1]] + ; WAVE32: S_ENDPGM 0, implicit [[FCMP]](s1) + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(false), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_oeq_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_oeq_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_EQ_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_EQ_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_oeq_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_EQ_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_EQ_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_EQ_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(oeq), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ogt_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_ogt_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_GT_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_GT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_GT_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_ogt_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_GT_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_GT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_GT_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(ogt), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_oge_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_oge_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_GE_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_GE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_GE_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_oge_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_GE_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_GE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_GE_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(oge), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_olt_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_olt_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_LT_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_LT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LT_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_olt_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_LT_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LT_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(olt), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ole_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_ole_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_LE_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_LE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LE_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_ole_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_LE_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LE_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(ole), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_one_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_one_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_LG_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_LG_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LG_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_one_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_LG_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LG_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LG_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(one), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ord_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_ord_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_O_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_O_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_O_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_ord_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_O_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_O_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_O_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(ord), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_uno_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_uno_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_U_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_U_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_U_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_uno_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_U_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_U_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_U_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(uno), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ueq_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_ueq_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_NLG_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLG_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLG_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_ueq_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_NLG_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLG_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLG_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(ueq), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ugt_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_ugt_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_NLE_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLE_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_ugt_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_NLE_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLE_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(ugt), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_uge_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_uge_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_NLT_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLT_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_uge_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_NLT_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLT_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(uge), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ult_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_ult_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_NGE_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_NGE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NGE_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_ult_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_NGE_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NGE_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NGE_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(ult), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_ule_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_ule_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_NGT_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_NGT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NGT_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_ule_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_NGT_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NGT_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NGT_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(ule), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_une_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_une_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE64: [[V_CMP_NEQ_F64_e64_:%[0-9]+]]:sreg_64 = V_CMP_NEQ_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NEQ_F64_e64_]] + ; WAVE32-LABEL: name: fcmp_une_s64_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vreg_64 = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vreg_64 = COPY $vgpr2_vgpr3 + ; WAVE32: [[V_CMP_NEQ_F64_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NEQ_F64_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NEQ_F64_e64_]] + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(une), %0, %1 + S_ENDPGM 0, implicit %2 +... + +--- +name: fcmp_true_s64_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + ; WAVE64-LABEL: name: fcmp_true_s64_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr(s64) = COPY $vgpr2_vgpr3 + ; WAVE64: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(true), [[COPY]](s64), [[COPY1]] + ; WAVE64: S_ENDPGM 0, implicit [[FCMP]](s1) + ; WAVE32-LABEL: name: fcmp_true_s64_vv + ; WAVE32: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr(s64) = COPY $vgpr2_vgpr3 + ; WAVE32: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(true), [[COPY]](s64), [[COPY1]] + ; WAVE32: S_ENDPGM 0, implicit [[FCMP]](s1) + %0:vgpr(s64) = COPY $vgpr0_vgpr1 + %1:vgpr(s64) = COPY $vgpr2_vgpr3 + %2:vcc(s1) = G_FCMP floatpred(true), %0, %1 + S_ENDPGM 0, implicit %2 +... Index: test/CodeGen/AMDGPU/GlobalISel/inst-select-fcmp.s16.mir =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/GlobalISel/inst-select-fcmp.s16.mir @@ -0,0 +1,444 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=instruction-select -verify-machineinstrs -global-isel-abort=0 -o - %s | FileCheck -check-prefix=WAVE64 %s +# RUN: llc -march=amdgcn -mcpu=gfx1010 -run-pass=instruction-select -verify-machineinstrs -global-isel-abort=0 -o - %s | FileCheck -check-prefix=WAVE32 %s + +--- +name: fcmp_false_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_false_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE64: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY]](s32) + ; WAVE64: [[TRUNC1:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY1]](s32) + ; WAVE64: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(false), [[TRUNC]](s16), [[TRUNC1]] + ; WAVE64: S_ENDPGM 0, implicit [[FCMP]](s1) + ; WAVE32-LABEL: name: fcmp_false_s16_vv + ; WAVE32: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE32: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY]](s32) + ; WAVE32: [[TRUNC1:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY1]](s32) + ; WAVE32: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(false), [[TRUNC]](s16), [[TRUNC1]] + ; WAVE32: S_ENDPGM 0, implicit [[FCMP]](s1) + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(false), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_oeq_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_oeq_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_EQ_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_EQ_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_EQ_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_oeq_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_EQ_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_EQ_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_EQ_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(oeq), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_ogt_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ogt_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_GT_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_GT_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_GT_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_ogt_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_GT_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_GT_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_GT_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(ogt), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_oge_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_oge_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_GE_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_GE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_GE_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_oge_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_GE_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_GE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_GE_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(oge), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_olt_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_olt_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_LT_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_LT_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LT_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_olt_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_LT_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LT_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LT_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(olt), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_ole_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ole_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_LE_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_LE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LE_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_ole_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_LE_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LE_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(ole), %2, %3 + S_ENDPGM 0, implicit %4 +... +--- +name: fcmp_one_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_one_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_LG_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_LG_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LG_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_one_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_LG_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LG_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LG_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(one), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_ord_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ord_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_LG_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_LG_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_LG_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_ord_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_LG_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_LG_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_LG_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(one), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_uno_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_uno_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_U_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_U_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_U_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_uno_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_U_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_U_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_U_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(uno), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_ueq_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ueq_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NLG_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLG_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLG_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_ueq_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NLG_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLG_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLG_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(ueq), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_ugt_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ugt_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NLE_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_NLE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NLE_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_ugt_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NLE_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NLE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NLE_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(ugt), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_uge_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_uge_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE64: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY]](s32) + ; WAVE64: [[TRUNC1:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY1]](s32) + ; WAVE64: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(uge), [[TRUNC]](s16), [[TRUNC1]] + ; WAVE64: S_ENDPGM 0, implicit [[FCMP]](s1) + ; WAVE32-LABEL: name: fcmp_uge_s16_vv + ; WAVE32: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE32: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY]](s32) + ; WAVE32: [[TRUNC1:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY1]](s32) + ; WAVE32: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(uge), [[TRUNC]](s16), [[TRUNC1]] + ; WAVE32: S_ENDPGM 0, implicit [[FCMP]](s1) + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(uge), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_ult_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ult_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NGE_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_NGE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NGE_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_ult_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NGE_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NGE_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NGE_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(ult), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_ule_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_ule_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NGT_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_NGT_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NGT_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_ule_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NGT_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NGT_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NGT_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(ule), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_une_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_une_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[V_CMP_NEQ_F16_e64_:%[0-9]+]]:sreg_64 = V_CMP_NEQ_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_CMP_NEQ_F16_e64_]] + ; WAVE32-LABEL: name: fcmp_une_s16_vv + ; WAVE32: $vcc_hi = IMPLICIT_DEF + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[V_CMP_NEQ_F16_e64_:%[0-9]+]]:sreg_32_xm0 = V_CMP_NEQ_F16_e64 0, [[COPY]], 0, [[COPY1]], 0, implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_CMP_NEQ_F16_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(une), %2, %3 + S_ENDPGM 0, implicit %4 +... + +--- +name: fcmp_true_s16_vv +legalized: true +regBankSelected: true + +body: | + bb.0: + liveins: $vgpr0, $vgpr1 + ; WAVE64-LABEL: name: fcmp_true_s16_vv + ; WAVE64: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE64: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY]](s32) + ; WAVE64: [[TRUNC1:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY1]](s32) + ; WAVE64: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(true), [[TRUNC]](s16), [[TRUNC1]] + ; WAVE64: S_ENDPGM 0, implicit [[FCMP]](s1) + ; WAVE32-LABEL: name: fcmp_true_s16_vv + ; WAVE32: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; WAVE32: [[TRUNC:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY]](s32) + ; WAVE32: [[TRUNC1:%[0-9]+]]:vgpr(s16) = G_TRUNC [[COPY1]](s32) + ; WAVE32: [[FCMP:%[0-9]+]]:vcc(s1) = G_FCMP floatpred(true), [[TRUNC]](s16), [[TRUNC1]] + ; WAVE32: S_ENDPGM 0, implicit [[FCMP]](s1) + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s16) = G_TRUNC %0 + %3:vgpr(s16) = G_TRUNC %1 + %4:vcc(s1) = G_FCMP floatpred(true), %2, %3 + S_ENDPGM 0, implicit %4 +... + Index: test/CodeGen/Mips/GlobalISel/instruction-select/mul.mir =================================================================== --- test/CodeGen/Mips/GlobalISel/instruction-select/mul.mir +++ test/CodeGen/Mips/GlobalISel/instruction-select/mul.mir @@ -49,11 +49,9 @@ ; MIPS32: [[MUL:%[0-9]+]]:gpr32 = MUL [[COPY]], [[COPY1]], implicit-def dead $hi0, implicit-def dead $lo0 ; MIPS32: [[PseudoMULTu:%[0-9]+]]:acc64 = PseudoMULTu [[COPY]], [[COPY1]] ; MIPS32: [[PseudoMFHI:%[0-9]+]]:gpr32 = PseudoMFHI [[PseudoMULTu]] - ; MIPS32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 0 - ; MIPS32: [[XOR:%[0-9]+]]:gpr32 = XOR [[PseudoMFHI]], [[ORi]] - ; MIPS32: [[SLTu:%[0-9]+]]:gpr32 = SLTu $zero, [[XOR]] - ; MIPS32: [[ORi1:%[0-9]+]]:gpr32 = ORi $zero, 1 - ; MIPS32: [[AND:%[0-9]+]]:gpr32 = AND [[SLTu]], [[ORi1]] + ; MIPS32: [[SLTu:%[0-9]+]]:gpr32 = SLTu $zero, [[PseudoMFHI]] + ; MIPS32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1 + ; MIPS32: [[AND:%[0-9]+]]:gpr32 = AND [[SLTu]], [[ORi]] ; MIPS32: SB [[AND]], [[COPY3]], 0 :: (store 1 into %ir.pcarry_flag) ; MIPS32: SW [[MUL]], [[COPY2]], 0 :: (store 4 into %ir.pmul) ; MIPS32: RetRA Index: test/CodeGen/Mips/GlobalISel/llvm-ir/icmp.ll =================================================================== --- test/CodeGen/Mips/GlobalISel/llvm-ir/icmp.ll +++ test/CodeGen/Mips/GlobalISel/llvm-ir/icmp.ll @@ -164,8 +164,6 @@ ; MIPS32-NEXT: xor $1, $4, $6 ; MIPS32-NEXT: xor $2, $5, $7 ; MIPS32-NEXT: or $1, $1, $2 -; MIPS32-NEXT: ori $2, $zero, 0 -; MIPS32-NEXT: xor $1, $1, $2 ; MIPS32-NEXT: sltiu $2, $1, 1 ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop @@ -180,8 +178,6 @@ ; MIPS32-NEXT: xor $1, $4, $6 ; MIPS32-NEXT: xor $2, $5, $7 ; MIPS32-NEXT: or $1, $1, $2 -; MIPS32-NEXT: ori $2, $zero, 0 -; MIPS32-NEXT: xor $1, $1, $2 ; MIPS32-NEXT: sltu $2, $zero, $1 ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop Index: test/CodeGen/Mips/GlobalISel/llvm-ir/mul.ll =================================================================== --- test/CodeGen/Mips/GlobalISel/llvm-ir/mul.ll +++ test/CodeGen/Mips/GlobalISel/llvm-ir/mul.ll @@ -186,8 +186,6 @@ ; MIPS32-NEXT: mul $1, $4, $5 ; MIPS32-NEXT: multu $4, $5 ; MIPS32-NEXT: mfhi $2 -; MIPS32-NEXT: ori $3, $zero, 0 -; MIPS32-NEXT: xor $2, $2, $3 ; MIPS32-NEXT: sltu $2, $zero, $2 ; MIPS32-NEXT: ori $3, $zero, 1 ; MIPS32-NEXT: and $2, $2, $3 Index: test/TableGen/Common/GlobalISelEmitterCommon.td =================================================================== --- test/TableGen/Common/GlobalISelEmitterCommon.td +++ test/TableGen/Common/GlobalISelEmitterCommon.td @@ -7,6 +7,7 @@ def GPR32Op : RegisterOperand; def F0 : Register<"f0"> { let Namespace = "MyTarget"; } def FPR32 : RegisterClass<"MyTarget", [f32], 32, (add F0)>; +def FPR32Op : RegisterOperand; def p0 : PtrValueType ; class I Pat> Index: test/TableGen/GlobalISelEmitter-setcc.td =================================================================== --- /dev/null +++ test/TableGen/GlobalISelEmitter-setcc.td @@ -0,0 +1,18 @@ +// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common %s -o - < %s | FileCheck -check-prefix=GISEL %s + +include "llvm/Target/Target.td" +include "GlobalISelEmitterCommon.td" + +// GISEL: GIM_Try +// GISEL: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4, +// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_FCMP, +// GISEL: GIM_CheckCmpPredicate, /*MI*/0, /*Op*/1, /*Predicate*/CmpInst::FCMP_OEQ, +def FCMPOEQ : I<(outs GPR32:$dst), (ins FPR32Op:$src0, FPR32:$src1), + [(set GPR32:$dst, (i32 (setcc f32:$src0, f32:$src1, SETOEQ)))]>; + +// GISEL: GIM_Try +// GISEL: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4, +// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_ICMP, +// GISEL: GIM_CheckCmpPredicate, /*MI*/0, /*Op*/1, /*Predicate*/CmpInst::ICMP_EQ, +def ICMPEQ : I<(outs GPR32:$dst), (ins GPR32Op:$src0, GPR32:$src1), + [(set GPR32:$dst, (i32 (setcc i32:$src0, i32:$src1, SETEQ)))]>; Index: utils/TableGen/GlobalISelEmitter.cpp =================================================================== --- utils/TableGen/GlobalISelEmitter.cpp +++ utils/TableGen/GlobalISelEmitter.cpp @@ -34,6 +34,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" +//#include "llvm/IR/InstrTypes.h" #include "llvm/Support/CodeGenCoverage.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" @@ -49,6 +50,78 @@ #define DEBUG_TYPE "gisel-emitter" +// Copy of CmpInst::Predicate. This can't directly use that, as it would +// introduce a circular dependency between the IR library and TableGen. +// TODO: Should this be moved to support/ +enum CmpPredicate { + // Opcode U L G E Intuitive operation + FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded) + FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal + FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than + FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal + FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than + FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal + FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal + FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans) + FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y) + FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal + FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than + FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal + FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than + FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal + FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal + FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded) + FIRST_FCMP_PREDICATE = FCMP_FALSE, + LAST_FCMP_PREDICATE = FCMP_TRUE, + BAD_FCMP_PREDICATE = FCMP_TRUE + 1, + ICMP_EQ = 32, ///< equal + ICMP_NE = 33, ///< not equal + ICMP_UGT = 34, ///< unsigned greater than + ICMP_UGE = 35, ///< unsigned greater or equal + ICMP_ULT = 36, ///< unsigned less than + ICMP_ULE = 37, ///< unsigned less or equal + ICMP_SGT = 38, ///< signed greater than + ICMP_SGE = 39, ///< signed greater or equal + ICMP_SLT = 40, ///< signed less than + ICMP_SLE = 41, ///< signed less or equal + FIRST_ICMP_PREDICATE = ICMP_EQ, + LAST_ICMP_PREDICATE = ICMP_SLE, + BAD_ICMP_PREDICATE = ICMP_SLE + 1 +}; + +static StringRef getCmpEnumName(CmpPredicate P) { + switch (P) { + case ICMP_EQ: return "ICMP_EQ"; + case ICMP_NE: return "ICMP_NE"; + case ICMP_UGT: return "ICMP_UGT"; + case ICMP_ULT: return "ICMP_ULT"; + case ICMP_UGE: return "ICMP_UGE"; + case ICMP_ULE: return "ICMP_ULE"; + case ICMP_SGT: return "ICMP_SGT"; + case ICMP_SLT: return "ICMP_SLT"; + case ICMP_SGE: return "ICMP_SGE"; + case ICMP_SLE: return "ICMP_SLE"; + case FCMP_OEQ: return "FCMP_OEQ"; + case FCMP_ONE: return "FCMP_ONE"; + case FCMP_OGT: return "FCMP_OGT"; + case FCMP_OLT: return "FCMP_OLT"; + case FCMP_OGE: return "FCMP_OGE"; + case FCMP_OLE: return "FCMP_OLE"; + case FCMP_UEQ: return "FCMP_UEQ"; + case FCMP_UNE: return "FCMP_UNE"; + case FCMP_UGT: return "FCMP_UGT"; + case FCMP_ULT: return "FCMP_ULT"; + case FCMP_UGE: return "FCMP_UGE"; + case FCMP_ULE: return "FCMP_ULE"; + case FCMP_ORD: return "FCMP_ORD"; + case FCMP_UNO: return "FCMP_UNO"; + case FCMP_TRUE: return "FCMP_TRUE"; + case FCMP_FALSE: return "FCMP_FALSE"; + default: + return ""; + } +} + STATISTIC(NumPatternTotal, "Total number of patterns"); STATISTIC(NumPatternImported, "Number of patterns imported from SelectionDAG"); STATISTIC(NumPatternImportsSkipped, "Number of SelectionDAG imports skipped"); @@ -1064,6 +1137,7 @@ OPM_SameOperand, OPM_ComplexPattern, OPM_IntrinsicID, + OPM_CmpPredicate, OPM_Instruction, OPM_Int, OPM_LiteralInt, @@ -1389,6 +1463,36 @@ } }; +/// Generates code to check that an operand is an CmpInst predicate +class CmpPredicateOperandMatcher : public OperandPredicateMatcher { +protected: + CmpPredicate Pred; + +public: + CmpPredicateOperandMatcher(unsigned InsnVarID, unsigned OpIdx, + CmpPredicate P) + : OperandPredicateMatcher(OPM_CmpPredicate, InsnVarID, OpIdx), Pred(P) {} + + bool isIdentical(const PredicateMatcher &B) const override { + return OperandPredicateMatcher::isIdentical(B) && + Pred == cast(&B)->Pred; + } + + static bool classof(const PredicateMatcher *P) { + return P->getKind() == OPM_CmpPredicate; + } + + void emitPredicateOpcodes(MatchTable &Table, + RuleMatcher &Rule) const override { + Table << MatchTable::Opcode("GIM_CheckCmpPredicate") + << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID) + << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx) + << MatchTable::Comment("Predicate") + << MatchTable::NamedValue("CmpInst", getCmpEnumName(Pred)) + << MatchTable::LineBreak; + } +}; + /// Generates code to check that an operand is an intrinsic ID. class IntrinsicIDOperandMatcher : public OperandPredicateMatcher { protected: @@ -3232,6 +3336,13 @@ const CodeGenInstruction * GlobalISelEmitter::getEquivNode(Record &Equiv, const TreePatternNode *N) const { + if (N->getOperator()->getName() == "setcc") { + // One operation maps to two different G_* instructions based on the type. + if (MVT(N->getChild(0)->getSimpleType(0)).isFloatingPoint()) + return &Target.getInstruction(RK.getDef("G_FCMP")); + return &Target.getInstruction(RK.getDef("G_ICMP")); + } + for (const TreePredicateCall &Call : N->getPredicateCalls()) { const TreePredicateFn &Predicate = Call.Fn; if (!Equiv.isValueUnset("IfSignExtend") && Predicate.isLoad() && @@ -3263,6 +3374,35 @@ return Error::success(); } +// Parse the ISD CondCode names to the corresponding CmpInst::Predicate +// FIXME: Need to move enum to avoid circular dependency +static CmpPredicate parseCondCodeName(StringRef CondCode, bool IsFP) { + const CmpPredicate Invalid = IsFP ? BAD_FCMP_PREDICATE : BAD_ICMP_PREDICATE; + + return StringSwitch(CondCode) + .Case("SETOEQ", FCMP_OEQ) + .Case("SETOGT", FCMP_OGT) + .Case("SETOGE", FCMP_OGE) + .Case("SETOLT", FCMP_OLT) + .Case("SETOLE", FCMP_OLE) + .Case("SETONE", FCMP_ONE) + .Case("SETO", FCMP_ORD) + .Case("SETUO", FCMP_UNO) + .Case("SETUEQ", FCMP_UEQ) + .Case("SETUGT", IsFP ? FCMP_UGT : ICMP_UGT) + .Case("SETUGE", IsFP ? FCMP_UGE : ICMP_UGE) + .Case("SETULT", IsFP ? FCMP_ULT : ICMP_ULT) + .Case("SETULE", IsFP ? FCMP_ULE : ICMP_ULE) + .Case("SETUNE", FCMP_UNE) + .Case("SETEQ", IsFP ? Invalid : ICMP_EQ) + .Case("SETGT", IsFP ? Invalid : ICMP_SGT) + .Case("SETGE", IsFP ? Invalid : ICMP_SGE) + .Case("SETLT", IsFP ? Invalid : ICMP_SLT) + .Case("SETLE", IsFP ? Invalid : ICMP_SLE) + .Case("SETNE", IsFP ? Invalid : ICMP_NE) + .Default(Invalid); +} + Expected GlobalISelEmitter::createAndImportSelDAGMatcher( RuleMatcher &Rule, InstructionMatcher &InsnMatcher, const TreePatternNode *Src, unsigned &TempOpIdx) { @@ -3481,8 +3621,36 @@ return InsnMatcher; } + + // Special case because the operand order is changed from setcc. The + // predicate operand needs to be swapped from the last operand to the first + // source. + + unsigned NumChildren = Src->getNumChildren(); + bool IsFCmp = SrcGIOrNull->TheDef->getName() == "G_FCMP"; + + if (IsFCmp || SrcGIOrNull->TheDef->getName() == "G_ICMP") { + TreePatternNode *SrcChild = Src->getChild(NumChildren - 1); + if (SrcChild->isLeaf()) { + DefInit *DI = dyn_cast(SrcChild->getLeafValue()); + if (!DI || !DI->getDef()->isSubClassOf("CondCode")) + return failedImport("Unable to handle CondCode"); + + OperandMatcher &OM = + InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx); + + CmpPredicate CC = parseCondCodeName(DI->getDef()->getName(), IsFCmp); + if (CC != BAD_FCMP_PREDICATE && CC != BAD_ICMP_PREDICATE) { + OM.addPredicate(CC); + + // Process the other 2 operands normally. + --NumChildren; + } + } + } + // Match the used operands (i.e. the children of the operator). - for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) { + for (unsigned i = 0; i != NumChildren; ++i) { TreePatternNode *SrcChild = Src->getChild(i); // SelectionDAG allows pointers to be represented with iN since it doesn't @@ -3502,7 +3670,7 @@ continue; } - return failedImport("Expected IntInit containing instrinsic ID)"); + return failedImport("Expected IntInit containing intrinsic ID)"); } if (auto Error =