From ea69bf92bb456723da8a8fd53a74a01f99293f0a Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 9 Mar 2017 22:02:14 +0000 Subject: [PATCH] [Hexagon] Fixes to the bitsplit generation - Fix the insertion point, which occasionally could have been incorrect. - Avoid creating multiple bitsplits with the same operands, if an old one could be reused. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297414 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Hexagon/HexagonBitSimplify.cpp | 57 ++++++++++++++++++----- test/CodeGen/Hexagon/bit-bitsplit-at.ll | 33 +++++++++++++ 2 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 test/CodeGen/Hexagon/bit-bitsplit-at.ll diff --git a/lib/Target/Hexagon/HexagonBitSimplify.cpp b/lib/Target/Hexagon/HexagonBitSimplify.cpp index 41d4f6c17e8..61f290ca98d 100644 --- a/lib/Target/Hexagon/HexagonBitSimplify.cpp +++ b/lib/Target/Hexagon/HexagonBitSimplify.cpp @@ -1744,10 +1744,11 @@ namespace { // This is by no means complete class BitSimplification : public Transformation { public: - BitSimplification(BitTracker &bt, const HexagonInstrInfo &hii, - const HexagonRegisterInfo &hri, MachineRegisterInfo &mri, - MachineFunction &mf) - : Transformation(true), HII(hii), HRI(hri), MRI(mri), MF(mf), BT(bt) {} + BitSimplification(BitTracker &bt, const MachineDominatorTree &mdt, + const HexagonInstrInfo &hii, const HexagonRegisterInfo &hri, + MachineRegisterInfo &mri, MachineFunction &mf) + : Transformation(true), MDT(mdt), HII(hii), HRI(hri), MRI(mri), + MF(mf), BT(bt) {} bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override; @@ -1781,6 +1782,11 @@ namespace { bool simplifyExtractLow(MachineInstr *MI, BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC, const RegisterSet &AVs); + // Cache of created instructions to avoid creating duplicates. + // XXX Currently only used by genBitSplit. + std::vector NewMIs; + + const MachineDominatorTree &MDT; const HexagonInstrInfo &HII; const HexagonRegisterInfo &HRI; MachineRegisterInfo &MRI; @@ -2252,14 +2258,43 @@ bool BitSimplification::genBitSplit(MachineInstr *MI, assert(DefS != nullptr); DebugLoc DL = DefS->getDebugLoc(); MachineBasicBlock &B = *DefS->getParent(); - auto At = MI->isPHI() ? B.getFirstNonPHI() - : MachineBasicBlock::iterator(DefS); + auto At = DefS->isPHI() ? B.getFirstNonPHI() + : MachineBasicBlock::iterator(DefS); if (MRI.getRegClass(SrcR)->getID() == Hexagon::DoubleRegsRegClassID) SrcSR = (std::min(Pos, P) == 32) ? Hexagon::isub_hi : Hexagon::isub_lo; - unsigned NewR = MRI.createVirtualRegister(&Hexagon::DoubleRegsRegClass); - BuildMI(B, At, DL, HII.get(Hexagon::A4_bitspliti), NewR) - .addReg(SrcR, 0, SrcSR) - .addImm(Pos <= P ? W-Z : Z); + if (!validateReg({SrcR,SrcSR}, Hexagon::A4_bitspliti, 1)) + continue; + unsigned ImmOp = Pos <= P ? W-Z : Z; + + // Find an existing bitsplit instruction if one already exists. + unsigned NewR = 0; + for (MachineInstr *In : NewMIs) { + if (In->getOpcode() != Hexagon::A4_bitspliti) + continue; + MachineOperand &Op1 = In->getOperand(1); + if (Op1.getReg() != SrcR || Op1.getSubReg() != SrcSR) + continue; + if (In->getOperand(2).getImm() != ImmOp) + continue; + // Check if the target register is available here. + MachineOperand &Op0 = In->getOperand(0); + MachineInstr *DefI = MRI.getVRegDef(Op0.getReg()); + assert(DefI != nullptr); + if (!MDT.dominates(DefI, &*At)) + continue; + + // Found one that can be reused. + assert(Op0.getSubReg() == 0); + NewR = Op0.getReg(); + break; + } + if (!NewR) { + NewR = MRI.createVirtualRegister(&Hexagon::DoubleRegsRegClass); + auto NewBS = BuildMI(B, At, DL, HII.get(Hexagon::A4_bitspliti), NewR) + .addReg(SrcR, 0, SrcSR) + .addImm(ImmOp); + NewMIs.push_back(NewBS); + } if (Pos <= P) { HBS::replaceRegWithSub(RD.Reg, NewR, Hexagon::isub_lo, MRI); HBS::replaceRegWithSub(S, NewR, Hexagon::isub_hi, MRI); @@ -2635,7 +2670,7 @@ bool HexagonBitSimplify::runOnMachineFunction(MachineFunction &MF) { BT.run(); RegisterSet ABS; // Available registers for BS. - BitSimplification BitS(BT, HII, HRI, MRI, MF); + BitSimplification BitS(BT, *MDT, HII, HRI, MRI, MF); Changed |= visitBlock(Entry, BitS, ABS); Changed = DeadCodeElimination(MF, *MDT).run() || Changed; diff --git a/test/CodeGen/Hexagon/bit-bitsplit-at.ll b/test/CodeGen/Hexagon/bit-bitsplit-at.ll new file mode 100644 index 00000000000..87d535fd0f2 --- /dev/null +++ b/test/CodeGen/Hexagon/bit-bitsplit-at.ll @@ -0,0 +1,33 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s +; REQUIRES: asserts + +; This testcase used to crash due to putting the bitsplit instruction in a +; wrong place. +; CHECK: bitsplit + +target triple = "hexagon" + +define hidden fastcc i32 @fred(i32 %a0) unnamed_addr #0 { +b1: + %v2 = lshr i32 %a0, 16 + %v3 = trunc i32 %v2 to i8 + br i1 undef, label %b6, label %b4 + +b4: ; preds = %b1 + %v5 = and i32 %a0, 65535 + br i1 undef, label %b8, label %b9 + +b6: ; preds = %b1 + %v7 = and i32 %a0, 65535 + br label %b9 + +b8: ; preds = %b4 + store i8 %v3, i8* undef, align 2 + unreachable + +b9: ; preds = %b6, %b4 + %v10 = phi i32 [ %v7, %b6 ], [ %v5, %b4 ] + ret i32 %v10 +} + +attributes #0 = { nounwind optsize "target-cpu"="hexagonv60" "target-features"="-hvx-double,-long-calls" } -- 2.50.1