Make sure the whole live range is covered when values are pruned twice.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 2 Oct 2012 21:46:39 +0000 (21:46 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 2 Oct 2012 21:46:39 +0000 (21:46 +0000)
JoinVals::pruneValues() calls LIS->pruneValue() to avoid conflicts when
overlapping two different values. This produces a set of live range end
points that are used to reconstruct the live range (with SSA update)
after joining the two registers.

When a value is pruned twice, the set of end points was insufficient:

  v1 = DEF
  v1 = REPLACE1
  v1 = REPLACE2
  KILL v1

The end point at KILL would only reconstruct the live range from
REPLACE2 to KILL, leaving the range REPLACE1-REPLACE2 dead.

Add REPLACE2 as an end point in this case so the full live range is
reconstructed.

This fixes PR13999.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165056 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/RegisterCoalescer.cpp
test/CodeGen/ARM/coalesce-subregs.ll

index f45072f1ac56b69148fa395ee3a8852cc55302e0..ad1f5f4f125c49924fb2981e0950d16a6151556c 100644 (file)
@@ -1733,11 +1733,15 @@ void JoinVals::pruneValues(JoinVals &Other,
       // This value takes precedence over the value in Other.LI.
       LIS->pruneValue(&Other.LI, Def, &EndPoints);
       // Remove <def,read-undef> flags. This def is now a partial redef.
-      if (!Def.isBlock())
+      if (!Def.isBlock()) {
         for (MIOperands MO(Indexes->getInstructionFromIndex(Def));
              MO.isValid(); ++MO)
           if (MO->isReg() && MO->isDef() && MO->getReg() == LI.reg)
             MO->setIsUndef(false);
+       // This value will reach instructions below, but we need to make sure
+       // the live range also reaches the instruction at Def.
+       EndPoints.push_back(Def);
+      }
       DEBUG(dbgs() << "\t\tpruned " << PrintReg(Other.LI.reg) << " at " << Def
                    << ": " << Other.LI << '\n');
       break;
index 8d7ded5be06ea181467fb08104a66a563caf1ef3..6e1f17dced1720c7f9d84a8fbc4e5dfbc522a678 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mcpu=cortex-a9 -new-coalescer | FileCheck %s
+; RUN: llc < %s -mcpu=cortex-a9 -verify-coalescing | FileCheck %s
 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
 target triple = "thumbv7-apple-ios0.0.0"
 
@@ -189,3 +189,28 @@ if.end:                                           ; preds = %entry, %if.then
 declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly
 
 declare void @llvm.arm.neon.vst1.v4f32(i8*, <4 x float>, i32) nounwind
+
+; CHECK: pr13999
+define void @pr13999() nounwind readonly {
+entry:
+ br i1 true, label %outer_loop, label %loop.end
+
+outer_loop:
+ %d = phi double [ 0.0, %entry ], [ %add, %after_inner_loop ]
+ %0 = insertelement <2 x double> <double 0.0, double 0.0>, double %d, i32 0
+ br i1 undef, label %after_inner_loop, label %inner_loop
+
+inner_loop:
+ br i1 true, label %after_inner_loop, label %inner_loop
+
+after_inner_loop:
+ %1 = phi <2 x double> [ %0, %outer_loop ], [ <double 0.0, double 0.0>,
+%inner_loop ]
+ %2 = extractelement <2 x double> %1, i32 1
+ %add = fadd double 1.0, %2
+ br i1 false, label %loop.end, label %outer_loop
+
+loop.end:
+ %d.end = phi double [ 0.0, %entry ], [ %add, %after_inner_loop ]
+ ret void
+}