From 3c99845d54d6b8202fd32ec0983b723c1fa4e671 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 11 Aug 2016 18:42:06 +0000 Subject: [PATCH] If-conversion incorrectly calculates liveness of redefined registers Differential Revision: https://reviews.llvm.org/D23207 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278383 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/IfConversion.cpp | 9 +++- test/CodeGen/Hexagon/ifcvt-impuse-livein.mir | 43 ++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/Hexagon/ifcvt-impuse-livein.mir diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index 109917ba2c0..22fe5288d8d 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -1689,10 +1689,15 @@ bool IfConverter::IfConvertDiamondCommon( // Remove the conditional branch from entry to the blocks. BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); - // Initialize liveins to the first BB. These are potentially redefined by - // predicated instructions. + // Initialize the Redefs: + // - BB2 live-in regs need implicit uses before being redefined by BB1 + // instructions. + // - BB1 live-out regs need implicit uses before being redefined by BB2 + // instructions. We start with BB1 live-ins so we have the live-out regs + // after tracking the BB1 instructions. Redefs.init(TRI); Redefs.addLiveIns(*BBI1->BB); + Redefs.addLiveIns(*BBI2->BB); // Remove the duplicated instructions at the beginnings of both paths. // Skip dbg_value instructions diff --git a/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir b/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir new file mode 100644 index 00000000000..83a1046357c --- /dev/null +++ b/test/CodeGen/Hexagon/ifcvt-impuse-livein.mir @@ -0,0 +1,43 @@ +# RUN: llc -march=hexagon -run-pass if-converter %s -o - | FileCheck %s + +# Make sure that the necessary implicit uses are added to predicated +# instructions. + +# CHECK-LABEL: name: foo + +--- | + define void @foo() { + ret void + } +... + +--- +name: foo +tracksRegLiveness: true +allVRegsAllocated: true +body: | + bb.0: + successors: %bb.1, %bb.2 + liveins: %r0, %r2, %p1 + J2_jumpf %p1, %bb.1, implicit-def %pc + J2_jump %bb.2, implicit-def %pc + bb.1: + successors: %bb.3 + liveins: %r2 + %r0 = A2_tfrsi 2 + J2_jump %bb.3, implicit-def %pc + bb.2: + successors: %bb.3 + liveins: %r0 + ; Even though r2 was not live on entry to this block, it was live across + ; block bb.1 in the original diamond. After if-conversion, the diamond + ; became a single block, and so r2 is now live on entry to the instructions + ; originating from bb.2. + ; CHECK: %r2 = C2_cmoveit %p1, 1, implicit %r2 + %r2 = A2_tfrsi 1 + bb.3: + liveins: %r0, %r2 + %r0 = A2_add %r0, %r2 + J2_jumpr %r31, implicit-def %pc +... +