From 8dfe3fb1f5f237cbc93fea3592bed701c02dc2d4 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 19 Apr 2018 08:25:46 -0700 Subject: [PATCH] [LLVM 6] add patch to diamond if-conversion --- deps/llvm.mk | 1 + deps/patches/llvm-6.0.0-ifconv-D45819.patch | 158 ++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 deps/patches/llvm-6.0.0-ifconv-D45819.patch diff --git a/deps/llvm.mk b/deps/llvm.mk index 44737ca3be220..a917d132736ea 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -481,6 +481,7 @@ $(eval $(call LLVM_PATCH,llvm-6.0.0_D27296-libssp)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-6.0-D44650)) # mingw32 build fix $(eval $(call LLVM_PATCH,llvm-D45008)) # remove for 7.0 $(eval $(call LLVM_PATCH,llvm-D45070)) # remove for 7.0 +$(eval $(call LLVM_PATCH,llvm-6.0.0-ifconv-D45819)) # remove for 7.0 endif # LLVM_VER # Remove hardcoded OS X requirements in compilter-rt cmake build diff --git a/deps/patches/llvm-6.0.0-ifconv-D45819.patch b/deps/patches/llvm-6.0.0-ifconv-D45819.patch new file mode 100644 index 0000000000000..0fcd5a906d325 --- /dev/null +++ b/deps/patches/llvm-6.0.0-ifconv-D45819.patch @@ -0,0 +1,158 @@ +Index: lib/CodeGen/IfConversion.cpp +=================================================================== +--- a/lib/CodeGen/IfConversion.cpp ++++ b/lib/CodeGen/IfConversion.cpp +@@ -1714,20 +1714,25 @@ + } + + // 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 @@ + 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 @@ + 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 @@ + // 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; + } + +Index: test/CodeGen/Hexagon/ifcvt-diamond-ret.mir +=================================================================== +--- /dev/null ++++ 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 ++... +Index: test/CodeGen/MIR/PowerPC/ifcvt-diamond-ret.mir +=================================================================== +--- /dev/null ++++ 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 ++