diff options
| -rw-r--r-- | llvm/lib/CodeGen/IfConversion.cpp | 10 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Hexagon/ifcvt-common-kill.mir | 34 |
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 +... |

