From c1605651dbe7d3db25fea3655b395bd55791752a Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Mon, 11 Jul 2022 20:03:52 -0400 Subject: [m88k] Handle G_TRUNC to S1 This is generated when a boolean is loaded from memory, and then used as input for G_BRCOND. Also improves selectCondBr() in general. --- .../Target/M88k/GISel/M88kInstructionSelector.cpp | 41 +++++++++++++++------- llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp | 4 +-- llvm/lib/Target/M88k/M88kInstrInfo.cpp | 7 ++++ llvm/test/CodeGen/M88k/cond.ll | 27 ++++++++++++++ 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp index 33711be..b3d1a37 100644 --- a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp @@ -363,25 +363,25 @@ bool M88kInstructionSelector::selectCondBr(MachineInstr &I, MachineBasicBlock &MBB, MachineRegisterInfo &MRI) const { assert(I.getOpcode() == TargetOpcode::G_BRCOND && "Unexpected G code"); - // Match combinations of G_BRCND and G_ICMP/G_FCMP + // Match combinations of G_BRCND and G_ICMP/G_FCMP or + // combinations of G_BRCOND and G_TRUNC of G_AND/G_XOR. // G_ICMP: $tst, $src1, $src2 // G_BRCOND: $tst, $truebb MachineInstr *MI = nullptr; - MachineOperand CC = I.getOperand(0); - MachineOperand BB = I.getOperand(1); + Register CC = I.getOperand(0).getReg(); + MachineBasicBlock *BB = I.getOperand(1).getMBB(); CmpInst::Predicate Pred; - Register LHS, RHS; + Register LHS, RHS, Reg; int64_t SImm16; - if (mi_match(CC.getReg(), MRI, - m_GICmp(m_Pred(Pred), m_Reg(LHS), m_ICst(SImm16))) && + if (mi_match(CC, MRI, m_GICmp(m_Pred(Pred), m_Reg(LHS), m_ICst(SImm16))) && isInt<16>(SImm16)) { if (SImm16 == 0) { CC0 CCCode = getCCforBCOND(Pred); MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::BCND)) .addImm(static_cast(CCCode)) .addReg(LHS) - .add(BB); + .addMBB(BB); } else { Register Temp = MRI.createVirtualRegister(&M88k::GPRRCRegClass); ICC CCCode = getCCforICMP(Pred); @@ -394,10 +394,9 @@ bool M88kInstructionSelector::selectCondBr(MachineInstr &I, MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::BB1)) .addImm(static_cast(CCCode)) .addReg(Temp, RegState::Kill) - .add(BB); + .addMBB(BB); } - } else if (mi_match(CC.getReg(), MRI, - m_GICmp(m_Pred(Pred), m_Reg(LHS), m_Reg(RHS)))) { + } else if (mi_match(CC, MRI, m_GICmp(m_Pred(Pred), m_Reg(LHS), m_Reg(RHS)))) { Register Temp = MRI.createVirtualRegister(&M88k::GPRRCRegClass); ICC CCCode = getCCforICMP(Pred); MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::CMPrr)) @@ -409,12 +408,28 @@ bool M88kInstructionSelector::selectCondBr(MachineInstr &I, MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::BB1)) .addImm(static_cast(CCCode)) .addReg(Temp, RegState::Kill) - .add(BB); + .addMBB(BB); + } else if (mi_match( + CC, MRI, + m_GTrunc(m_any_of(m_GAnd(m_Reg(Reg), m_SpecificICst(1)), + m_GXor(m_GXor(m_Reg(Reg), m_SpecificICst(1)), + m_SpecificICst(1)))))) { + // TODO The xor(xor %r, 1), 1) pattern should be handled by a combiner. + MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::BB1)) + .addImm(0) + .addReg(Reg) + .addMBB(BB); + } else if (mi_match(CC, MRI, + m_GTrunc(m_GXor(m_Reg(Reg), m_SpecificICst(1))))) { + MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::BB0)) + .addImm(0) + .addReg(Reg) + .addMBB(BB); } else { MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::BB1)) - .add(I.getOperand(0)) .addImm(0) - .add(I.getOperand(1)); + .addReg(CC) + .addMBB(BB); } I.eraseFromParent(); diff --git a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp index 2a598e9..6c817ed 100644 --- a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp @@ -50,9 +50,7 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) { .legalIf([](const LegalityQuery &Query) { return false; }) .maxScalar(0, S32); getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({S32}); - getActionDefinitionsBuilder(G_TRUNC) - .legalIf([](const LegalityQuery &Query) { return false; }) - .maxScalar(1, S32); + getActionDefinitionsBuilder(G_TRUNC).alwaysLegal(); getActionDefinitionsBuilder({G_SEXTLOAD, G_ZEXTLOAD}) .legalForTypesWithMemDesc({{S32, P0, S8, 8}, {S32, P0, S16, 16}}); getActionDefinitionsBuilder({G_LOAD, G_STORE}) diff --git a/llvm/lib/Target/M88k/M88kInstrInfo.cpp b/llvm/lib/Target/M88k/M88kInstrInfo.cpp index 179f8e3..5c8550e 100644 --- a/llvm/lib/Target/M88k/M88kInstrInfo.cpp +++ b/llvm/lib/Target/M88k/M88kInstrInfo.cpp @@ -311,6 +311,7 @@ bool M88kInstrInfo::reverseBranchCondition( // Invert bits to get reverse condition. Cond[1].setImm(~Cond[1].getImm() & 0x0f); break; +#if 0 case M88k::BB1: case M88k::BB0: { // TODO This only works if the value was produced by cmp/fcmp. @@ -322,6 +323,12 @@ bool M88kInstrInfo::reverseBranchCondition( Cond[1].setImm(CC); break; } +#else + case M88k::BB1: + case M88k::BB0: + // The save way is to delare that the condition cannot be reversed. + return true; +#endif default: return true; } diff --git a/llvm/test/CodeGen/M88k/cond.ll b/llvm/test/CodeGen/M88k/cond.ll index 114c2f5..fccc9e9 100644 --- a/llvm/test/CodeGen/M88k/cond.ll +++ b/llvm/test/CodeGen/M88k/cond.ll @@ -35,3 +35,30 @@ compute: exit: ret i32 0 } + +define i32 @f3(i1 noundef zeroext %cnd) { +; CHECK-LABEL: f3: +; CHECK: bb0.n 0, {{%r[0-9]+}}, .{{[A-Z0-9]+}} +; CHECK: jmp %r1 + br i1 %cnd, label %true, label %false + +true: + ret i32 42 + +false: + ret i32 84 +} + +define i32 @f4(i1 noundef zeroext %cnd) { +; CHECK-LABEL: f4: +; CHECK: bb1.n 0, {{%r[0-9]+}}, .{{[A-Z0-9]+}} +; CHECK: jmp %r1 + %not = xor i1 %cnd, true + br i1 %not, label %true, label %false + +true: + ret i32 42 + +false: + ret i32 84 +} -- cgit v1.1