[PATCH] D51028: [BranchFolder] Drop kill flags if they aren't present in all merged instructions
Mikael Holmén via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 21 01:37:40 PDT 2018
uabelho created this revision.
uabelho added reviewers: kparzysz, gberry.
Just like we do with undef flags, we need to drop kill flags if they aren't
present in all merged instructions. Otherwise we would merge
<instr1> $r0
<instr2> killed $r0
and
<instr1> killed $r0
<instr2> undef $r0
into
<instr1> killed $r0
<instr2> $r0
and then the verifier would complain about $r0 not being live at <instr2>.
Repository:
rL LLVM
https://reviews.llvm.org/D51028
Files:
lib/CodeGen/BranchFolding.cpp
test/CodeGen/Hexagon/branchfolder-clear-kill.mir
Index: test/CodeGen/Hexagon/branchfolder-clear-kill.mir
===================================================================
--- /dev/null
+++ test/CodeGen/Hexagon/branchfolder-clear-kill.mir
@@ -0,0 +1,47 @@
+# RUN: llc -march=hexagon -run-pass branch-folder %s -o - -verify-machineinstrs | FileCheck %s
+
+# When the branchfolder merges common tails, it needs to clear both undef and
+# killed flags if they differ between the merged blocks.
+
+# In the below example, if the killed flag is not cleared we will be left with
+# A2_nop 0, killed $r0
+# A2_nop 0, $r0
+# and then the verifier will complain about use of an undefined physical
+# register.
+
+---
+# CHECK-LABEL: name: func0
+# CHECK-LABEL: bb.0:
+# CHECK: liveins: $r0, $r31
+# CHECK: A2_nop implicit $r0
+# CHECK: A2_nop implicit $r0
+# CHECK: PS_jmpret
+
+name: func0
+tracksRegLiveness: true
+
+body: |
+ bb.0:
+ liveins: $r0, $r31
+ successors: %bb.1, %bb.2
+ J2_jumpt undef $p0, %bb.2, implicit-def $pc
+ J2_jump %bb.1, implicit-def $pc
+
+ bb.1:
+ liveins: $r0, $r31
+ successors: %bb.3
+ A2_nop implicit $r0
+ A2_nop implicit killed $r0
+ J2_jump %bb.3, implicit-def $pc
+
+ bb.2:
+ liveins: $r0, $r31
+ successors: %bb.3
+ A2_nop implicit killed $r0
+ A2_nop implicit undef $r0
+ J2_jump %bb.3, implicit-def $pc
+
+ bb.3:
+ liveins: $r31
+ PS_jmpret killed $r31, implicit-def $pc
+...
Index: lib/CodeGen/BranchFolding.cpp
===================================================================
--- lib/CodeGen/BranchFolding.cpp
+++ lib/CodeGen/BranchFolding.cpp
@@ -866,14 +866,29 @@
// Merge MMOs from memory operations in the common block.
if (MBBICommon->mayLoad() || MBBICommon->mayStore())
MBBICommon->cloneMergedMemRefs(*MBB->getParent(), {&*MBBICommon, &*MBBI});
- // Drop undef flags if they aren't present in all merged instructions.
+ // Drop undef/kill flags if they aren't present in all merged instructions.
for (unsigned I = 0, E = MBBICommon->getNumOperands(); I != E; ++I) {
MachineOperand &MO = MBBICommon->getOperand(I);
if (MO.isReg() && MO.isUndef()) {
const MachineOperand &OtherMO = MBBI->getOperand(I);
if (!OtherMO.isUndef())
MO.setIsUndef(false);
}
+ if (MO.isReg() && MO.isKill()) {
+ const MachineOperand &OtherMO = MBBI->getOperand(I);
+ // An expection to the clearing of the kill flag is if we merge
+ // something like:
+ // <instr1> undef $r0
+ // $r0 = <instr2>
+ // and
+ // <instr1> killed $r0
+ // $r0 = <instr2>
+ // Here we should keep the kill flag even if it's only set in one of the
+ // merged paths since it's undef in the other. So the only real value
+ // in $r0 that actually reaches <instr1> will indeed be killed there.
+ if (!OtherMO.isKill() && !OtherMO.isUndef())
+ MO.setIsKill(false);
+ }
}
++MBBI;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51028.161665.patch
Type: text/x-patch
Size: 2989 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180821/52947851/attachment.bin>
More information about the llvm-commits
mailing list