summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/IfConversion.cpp10
-rw-r--r--llvm/test/CodeGen/Hexagon/ifcvt-common-kill.mir34
2 files changed, 40 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp
index 7d152b10753..a0ce2541583 100644
--- a/llvm/lib/CodeGen/IfConversion.cpp
+++ b/llvm/lib/CodeGen/IfConversion.cpp
@@ -1764,6 +1764,12 @@ bool IfConverter::IfConvertDiamondCommon(
Redefs.stepForward(MI, Dummy);
}
}
+ // Kill flags in the true block for registers living into the false block
+ // must be removed. This should be done before extracting the common
+ // instructions from the beginning of the MBB1, since these instructions
+ // can actually differ between MBB1 and MBB2 in terms of <kill> flags.
+ RemoveKills(MBB1.begin(), MBB1.end(), DontKill, *TRI);
+
BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.begin(), DI1);
MBB2.erase(MBB2.begin(), DI2);
@@ -1788,10 +1794,6 @@ bool IfConverter::IfConvertDiamondCommon(
}
MBB1.erase(DI1, MBB1.end());
- // Kill flags in the true block for registers living into the false block
- // must be removed.
- RemoveKills(MBB1.begin(), MBB1.end(), DontKill, *TRI);
-
DI2 = BBI2->BB->end();
// The branches have been checked to match. Skip over the branch in the false
// block so that we don't try to predicate it.
diff --git a/llvm/test/CodeGen/Hexagon/ifcvt-common-kill.mir b/llvm/test/CodeGen/Hexagon/ifcvt-common-kill.mir
new file mode 100644
index 00000000000..20b421d0aed
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/ifcvt-common-kill.mir
@@ -0,0 +1,34 @@
+# RUN: llc -march=hexagon -run-pass if-converter -o - %s -verify-machineinstrs | FileCheck %s
+
+# CHECK: %r26 = A2_tfr %r1
+# CHECK: S2_pstorerhf_io undef %p0, undef %r0, 0, killed %r1
+
+---
+name: foo
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1, %bb.2
+ liveins: %r0, %r1
+ J2_jumpf undef %p0, %bb.2, implicit-def %pc
+
+ bb.1:
+ successors: %bb.3
+ liveins: %r1
+ ; This <kill> flag should be cleared. It didn't use to be, because
+ ; this instruction is treated as a duplicate of the corresponding
+ ; instruction from the "false" block bb.2. Clearing of the <kill>
+ ; flags was limited to the non-common part of the "true" block.
+ %r26 = A2_tfr killed %r1
+ J2_jump %bb.3, implicit-def %pc
+
+ bb.2:
+ successors: %bb.3
+ liveins: %r1
+ %r26 = A2_tfr %r1
+ S2_storerh_io undef %r0, 0, killed %r1
+ J2_jump %bb.3, implicit-def %pc
+
+ bb.3:
+ liveins: %r26
+...
OpenPOWER on IntegriCloud