From 570c6440cd96efde5a8325f5fdc9ae8944f29aab Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 23 Mar 2018 17:46:09 +0000 Subject: [PATCH] [Hexagon] Two fixes in early if-conversion - Fix checking for vector predicate registers. - Avoid speculating llvm.lifetime.end intrinsic. Patch by Harsha Jagasia and Brendon Cahoon. llvm-svn: 328339 --- llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp | 21 +++--- .../CodeGen/Hexagon/early-if-conv-lifetime.mir | 75 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 llvm/test/CodeGen/Hexagon/early-if-conv-lifetime.mir diff --git a/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp b/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp index 11a042d..8410dc4 100644 --- a/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp +++ b/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp @@ -191,6 +191,7 @@ namespace { bool isProfitable(const FlowPattern &FP) const; bool isPredicableStore(const MachineInstr *MI) const; bool isSafeToSpeculate(const MachineInstr *MI) const; + bool isPredicate(unsigned R) const; unsigned getCondStoreOpcode(unsigned Opc, bool IfTrue) const; void predicateInstr(MachineBasicBlock *ToB, MachineBasicBlock::iterator At, @@ -387,13 +388,8 @@ bool HexagonEarlyIfConversion::isValidCandidate(const MachineBasicBlock *B) unsigned R = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(R)) continue; - switch (MRI->getRegClass(R)->getID()) { - case Hexagon::PredRegsRegClassID: - case Hexagon::HvxQRRegClassID: - break; - default: - continue; - } + if (!isPredicate(R)) + continue; for (auto U = MRI->use_begin(R); U != MRI->use_end(); ++U) if (U->getParent()->isPHI()) return false; @@ -443,8 +439,7 @@ bool HexagonEarlyIfConversion::isValid(const FlowPattern &FP) const { if (usesUndefVReg(&MI)) return false; unsigned DefR = MI.getOperand(0).getReg(); - const TargetRegisterClass *RC = MRI->getRegClass(DefR); - if (RC == &Hexagon::PredRegsRegClass) + if (isPredicate(DefR)) return false; } } @@ -680,10 +675,18 @@ bool HexagonEarlyIfConversion::isSafeToSpeculate(const MachineInstr *MI) return false; if (MI->hasUnmodeledSideEffects()) return false; + if (MI->getOpcode() == TargetOpcode::LIFETIME_END) + return false; return true; } +bool HexagonEarlyIfConversion::isPredicate(unsigned R) const { + const TargetRegisterClass *RC = MRI->getRegClass(R); + return RC == &Hexagon::PredRegsRegClass || + RC == &Hexagon::HvxQRRegClass; +} + unsigned HexagonEarlyIfConversion::getCondStoreOpcode(unsigned Opc, bool IfTrue) const { return HII->getCondOpcode(Opc, !IfTrue); diff --git a/llvm/test/CodeGen/Hexagon/early-if-conv-lifetime.mir b/llvm/test/CodeGen/Hexagon/early-if-conv-lifetime.mir new file mode 100644 index 0000000..bbb2dce --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/early-if-conv-lifetime.mir @@ -0,0 +1,75 @@ +# RUN: llc -march=hexagon -run-pass hexagon-early-if %s -o - | FileCheck %s + +# Test that the LIFETIME_END instruction is not speculated and moved to a +# different basic block. + +# CHECK: bb.1.b1: +# CHECK: LIFETIME_END +# CHECK: bb.2.b2: + +--- | + + %s.0 = type { %s.1 } + %s.1 = type { %s.2 } + %s.2 = type { %s.3 } + %s.3 = type { %s.4 } + %s.4 = type { %s.5 } + %s.5 = type { i32, i32, i8* } + + declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #0 + + define hidden fastcc void @f0() { + b0: + %v0 = alloca %s.0, align 4 + %v1 = load i8, i8* undef, align 1 + %v2 = add i8 %v1, -102 + %v3 = icmp ult i8 %v2, 1 + br i1 %v3, label %b1, label %b2 + + b1: ; preds = %b0 + %v4 = bitcast %s.0* %v0 to i8* + call void @llvm.lifetime.end.p0i8(i64 12, i8* nonnull %v4) + br label %b2 + + b2: ; preds = %b1, %b0 + ret void + } + + attributes #0 = { argmemonly nounwind } + +... +--- +name: f0 +alignment: 4 +registers: + - { id: 0, class: intregs, preferred-register: '' } + - { id: 1, class: intregs, preferred-register: '' } + - { id: 2, class: predregs, preferred-register: '' } + - { id: 3, class: predregs, preferred-register: '' } +liveins: +frameInfo: + maxAlignment: 4 +fixedStack: +stack: + - { id: 0, name: v0, type: default, offset: 0, size: 12, alignment: 4 } +constants: +body: | + bb.0.b0: + successors: %bb.1.b1(0x40000000), %bb.2.b2(0x40000000) + + %1 = IMPLICIT_DEF + %0 = L2_loadrb_io killed %1, 0 :: (load 1 from `i8* undef`) + %2 = C2_cmpeqi killed %0, 102 + %3 = COPY killed %2 + J2_jumpf killed %3, %bb.2.b2, implicit-def dead $pc + J2_jump %bb.1.b1, implicit-def dead $pc + + bb.1.b1: + successors: %bb.2.b2(0x80000000) + + LIFETIME_END %stack.0.v0 + + bb.2.b2: + PS_jmpret $r31, implicit-def dead $pc + +... -- 2.7.4