diff options
author | Tom Stellard <tstellar@redhat.com> | 2018-05-30 16:51:22 +0000 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2018-05-30 16:51:22 +0000 |
commit | 374c27a4de76f18db7e2474ff050b226aabfbd61 (patch) | |
tree | 2413603a6e1e05e89a1b9d4971834472dcb9fc9b | |
parent | 64dcc854c86dd5bb320aeb1e348219654ad42235 (diff) | |
download | llvm-374c27a4de76f18db7e2474ff050b226aabfbd61.tar.gz |
Merging r330345:
------------------------------------------------------------------------
r330345 | kparzysz | 2018-04-19 10:26:46 -0700 (Thu, 19 Apr 2018) | 8 lines
[if-converter] Handle BBs that terminate in ret during diamond conversion
This fixes https://llvm.org/PR36825.
Original patch by Valentin Churavy (D45218).
Differential Revision: https://reviews.llvm.org/D45731
------------------------------------------------------------------------
llvm-svn: 333561
-rw-r--r-- | llvm/lib/CodeGen/IfConversion.cpp | 39 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/ifcvt-diamond-ret.mir | 25 | ||||
-rw-r--r-- | llvm/test/CodeGen/MIR/PowerPC/ifcvt-diamond-ret.mir | 34 |
3 files changed, 87 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp index a22ce0dab9c2..d8ce90e63a9d 100644 --- a/llvm/lib/CodeGen/IfConversion.cpp +++ b/llvm/lib/CodeGen/IfConversion.cpp @@ -1714,20 +1714,25 @@ bool IfConverter::IfConvertDiamondCommon( } // Remove the duplicated instructions at the beginnings of both paths. - // Skip dbg_value instructions + // Skip dbg_value instructions. MachineBasicBlock::iterator DI1 = MBB1.getFirstNonDebugInstr(); MachineBasicBlock::iterator DI2 = MBB2.getFirstNonDebugInstr(); BBI1->NonPredSize -= NumDups1; BBI2->NonPredSize -= NumDups1; // Skip past the dups on each side separately since there may be - // differing dbg_value entries. + // differing dbg_value entries. NumDups1 can include a "return" + // instruction, if it's not marked as "branch". for (unsigned i = 0; i < NumDups1; ++DI1) { + if (DI1 == MBB1.end()) + break; if (!DI1->isDebugValue()) ++i; } while (NumDups1 != 0) { ++DI2; + if (DI2 == MBB2.end()) + break; if (!DI2->isDebugValue()) --NumDups1; } @@ -1738,11 +1743,16 @@ bool IfConverter::IfConvertDiamondCommon( Redefs.stepForward(MI, Dummy); } } + BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.begin(), DI1); MBB2.erase(MBB2.begin(), DI2); - // The branches have been checked to match, so it is safe to remove the branch - // in BB1 and rely on the copy in BB2 + // The branches have been checked to match, so it is safe to remove the + // branch in BB1 and rely on the copy in BB2. The complication is that + // the blocks may end with a return instruction, which may or may not + // be marked as "branch". If it's not, then it could be included in + // "dups1", leaving the blocks potentially empty after moving the common + // duplicates. #ifndef NDEBUG // Unanalyzable branches must match exactly. Check that now. if (!BBI1->IsBrAnalyzable) @@ -1768,11 +1778,14 @@ bool IfConverter::IfConvertDiamondCommon( if (RemoveBranch) BBI2->NonPredSize -= TII->removeBranch(*BBI2->BB); else { - do { - assert(DI2 != MBB2.begin()); - DI2--; - } while (DI2->isBranch() || DI2->isDebugValue()); - DI2++; + // Make DI2 point to the end of the range where the common "tail" + // instructions could be found. + while (DI2 != MBB2.begin()) { + MachineBasicBlock::iterator Prev = std::prev(DI2); + if (!Prev->isBranch() && !Prev->isDebugValue()) + break; + DI2 = Prev; + } } while (NumDups2 != 0) { // NumDups2 only counted non-dbg_value instructions, so this won't @@ -1833,11 +1846,15 @@ bool IfConverter::IfConvertDiamondCommon( // a non-predicated in BBI2, then we don't want to predicate the one from // BBI2. The reason is that if we merged these blocks, we would end up with // two predicated terminators in the same block. + // Also, if the branches in MBB1 and MBB2 were non-analyzable, then don't + // predicate them either. They were checked to be identical, and so the + // same branch would happen regardless of which path was taken. if (!MBB2.empty() && (DI2 == MBB2.end())) { MachineBasicBlock::iterator BBI1T = MBB1.getFirstTerminator(); MachineBasicBlock::iterator BBI2T = MBB2.getFirstTerminator(); - if (BBI1T != MBB1.end() && TII->isPredicated(*BBI1T) && - BBI2T != MBB2.end() && !TII->isPredicated(*BBI2T)) + bool BB1Predicated = BBI1T != MBB1.end() && TII->isPredicated(*BBI1T); + bool BB2NonPredicated = BBI2T != MBB2.end() && !TII->isPredicated(*BBI2T); + if (BB2NonPredicated && (BB1Predicated || !BBI2->IsBrAnalyzable)) --DI2; } diff --git a/llvm/test/CodeGen/Hexagon/ifcvt-diamond-ret.mir b/llvm/test/CodeGen/Hexagon/ifcvt-diamond-ret.mir new file mode 100644 index 000000000000..e896d9aaa9a4 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/ifcvt-diamond-ret.mir @@ -0,0 +1,25 @@ +# RUN: llc -march=hexagon -run-pass if-converter %s -o - | FileCheck %s + +# Make sure this gets if-converted and it doesn't crash. +# CHECK-LABEL: bb.0 +# CHECK: PS_jmpret %r31 +# CHECK-NOT: bb.{{[1-9]+}}: + +--- +name: fred +tracksRegLiveness: true +body: | + bb.0: + successors: %bb.1, %bb.2 + liveins: %r0 + renamable %p0 = C2_cmpeqi killed renamable %r0, 0 + J2_jumpf killed renamable %p0, %bb.2, implicit-def dead %pc + + bb.1: + S4_storeiri_io undef renamable %r0, 0, 32768 :: (store 4 into `i32* undef`) + PS_jmpret %r31, implicit-def dead %pc + + bb.2: + S4_storeiri_io undef renamable %r0, 0, 32768 :: (store 4 into `i32* undef`) + PS_jmpret %r31, implicit-def dead %pc +... diff --git a/llvm/test/CodeGen/MIR/PowerPC/ifcvt-diamond-ret.mir b/llvm/test/CodeGen/MIR/PowerPC/ifcvt-diamond-ret.mir new file mode 100644 index 000000000000..c63c055c3b31 --- /dev/null +++ b/llvm/test/CodeGen/MIR/PowerPC/ifcvt-diamond-ret.mir @@ -0,0 +1,34 @@ +# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -run-pass=if-converter %s -o - | FileCheck %s +--- +name: foo +body: | + bb.0: + liveins: %x0, %x3 + successors: %bb.1(0x40000000), %bb.2(0x40000000) + + dead renamable %x3 = ANDIo8 killed renamable %x3, 1, implicit-def dead %cr0, implicit-def %cr0gt + %cr2lt = CROR %cr0gt, %cr0gt + BCn killed renamable %cr2lt, %bb.2 + B %bb.1 + + bb.1: + renamable %x3 = LIS8 4096 + MTLR8 %x0, implicit-def %lr8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 + + bb.2: + renamable %x3 = LIS8 4096 + MTLR8 %x0, implicit-def %lr8 + BLR8 implicit %lr8, implicit %rm, implicit %x3 +... + +# Diamond testcase with equivalent branches terminating in returns. + +# CHECK: body: | +# CHECK: bb.0: +# CHECK: dead renamable %x3 = ANDIo8 killed renamable %x3, 1, implicit-def dead %cr0, implicit-def %cr0gt +# CHECK: %cr2lt = CROR %cr0gt, %cr0gt +# CHECK: renamable %x3 = LIS8 4096 +# CHECK: MTLR8 %x0, implicit-def %lr8 +# CHECK: BLR8 implicit %lr8, implicit %rm, implicit %x3 + |