Index: llvm/lib/CodeGen/RegAllocGreedy.cpp =================================================================== --- llvm/lib/CodeGen/RegAllocGreedy.cpp +++ llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -2420,20 +2420,26 @@ return 0; // Local intervals are handled separately. - if (LIS->intervalIsInOneMBB(VirtReg)) { + bool TryLocal = LIS->intervalIsInOneMBB(VirtReg) + if (TryLocal) { NamedRegionTimer T("local_split", "Local Splitting", TimerGroupName, TimerGroupDescription, TimePassesIsEnabled); SA->analyze(&VirtReg); - unsigned PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs); - if (PhysReg || !NewVRegs.empty()) - return PhysReg; + // We may have two disjoint uses in a single block. + if (SA->getUseBlocks().size() == 1) { + unsigned PhysReg = tryLocalSplit(VirtReg, Order, NewVRegs); + if (PhysReg || !NewVRegs.empty()) + return PhysReg; + } return tryInstructionSplit(VirtReg, Order, NewVRegs); } NamedRegionTimer T("global_split", "Global Splitting", TimerGroupName, TimerGroupDescription, TimePassesIsEnabled); - SA->analyze(&VirtReg); + // Don't reanalyze if local_split failed. + if (!TryLocal) + SA->analyze(&VirtReg); // FIXME: SplitAnalysis may repair broken live ranges coming from the // coalescer. That may cause the range to become allocatable which means that Index: llvm/test/CodeGen/X86/pr38795.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/pr38795.ll @@ -0,0 +1,188 @@ +; ModuleID = '/usr/local/google/home/niravd/pr38795.c' +source_filename = "/usr/local/google/home/niravd/pr38795.c" +target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" +target triple = "i386-unknown-linux-gnu" + +@c = common dso_local local_unnamed_addr global i8 0, align 1 +@.str = private unnamed_addr constant [6 x i8] c"%lld\0A\00", align 1 +@f = common dso_local local_unnamed_addr global i64 0, align 8 +@a = common dso_local local_unnamed_addr global i32 0, align 4 +@h = common dso_local local_unnamed_addr global i32 0, align 4 +@d = common dso_local local_unnamed_addr global i16 0, align 2 +@b = common dso_local local_unnamed_addr global i32 0, align 4 +@g = common dso_local local_unnamed_addr global i8 0, align 1 +@e = common dso_local local_unnamed_addr global i32 0, align 4 + +; Function Attrs: noreturn nounwind +define dso_local void @fn() #0 { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %l.0 = phi i16 [ undef, %entry ], [ %l.3, %for.inc ] + %m.0 = phi i32 [ undef, %entry ], [ %m.2, %for.inc ] + %n.0 = phi i32 [ 1, %entry ], [ %n.2, %for.inc ] + %i.0 = phi i32 [ undef, %entry ], [ %i.2, %for.inc ] + %o.0 = phi i32 [ undef, %entry ], [ %o.1, %for.inc ] + %p.0 = phi i8 [ undef, %entry ], [ %p.2, %for.inc ] + %k.0 = phi i8 [ undef, %entry ], [ %k.2, %for.inc ] + %q.0 = phi i32 [ undef, %entry ], [ %q.2, %for.inc ] + %0 = load i8, i8* @c, align 1, !tbaa !3 + %tobool = icmp ne i8 %0, 0 + %cmp = icmp ugt i8 %k.0, 8 + %or.cond61 = or i1 %cmp, %tobool + br i1 %or.cond61, label %if.then, label %if.end + +if.then: ; preds = %for.cond + %1 = load i64, i64* @f, align 8, !tbaa !6 + %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i64 %1) + br label %for.cond35 + +if.end: ; preds = %for.cond + %2 = load i32, i32* @a, align 4, !tbaa !8 + %div = sdiv i32 %m.0, %2 + %conv4 = trunc i32 %div to i16 + %tobool7 = icmp eq i16 %conv4, 0 + br label %ac + +ac: ; preds = %ac, %if.end + br i1 %tobool7, label %if.end9, label %ac + +if.end9: ; preds = %ac + %conv3 = trunc i32 %m.0 to i8 + %conv5 = sext i16 %l.0 to i32 + store i32 %conv5, i32* @h, align 4, !tbaa !8 + %conv6.le = trunc i32 %2 to i16 + %cmp11 = icmp slt i8 %k.0, 9 + br i1 %cmp11, label %if.then13, label %if.end21 + +if.then13: ; preds = %if.end9 + %3 = load i16, i16* @d, align 2, !tbaa !10 + %conv14 = sext i16 %3 to i64 + %call15 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i64 %conv14) + %4 = load i32, i32* @a, align 4, !tbaa !8 + %tobool16 = icmp eq i32 %4, 0 + br i1 %tobool16, label %for.inc, label %for.cond35 + +if.end21: ; preds = %if.end9 + %5 = load i8, i8* @g, align 1, !tbaa !3 + %conv22 = sext i8 %5 to i32 + br label %ae + +ae: ; preds = %for.cond47, %if.end21 + %l.2 = phi i16 [ %conv6.le, %if.end21 ], [ %l.7, %for.cond47 ] + %m.1 = phi i32 [ %div, %if.end21 ], [ %m.6, %for.cond47 ] + %n.1 = phi i32 [ %n.0, %if.end21 ], [ %n.7, %for.cond47 ] + %i.1 = phi i32 [ %i.0, %if.end21 ], [ %i.5, %for.cond47 ] + %p.1 = phi i8 [ %k.0, %if.end21 ], [ %p.6, %for.cond47 ] + %k.1 = phi i8 [ %conv3, %if.end21 ], [ %k.6, %for.cond47 ] + %q.1 = phi i32 [ %conv22, %if.end21 ], [ %q.5, %for.cond47 ] + %6 = load i8, i8* @c, align 1, !tbaa !3 + %conv23 = sext i8 %6 to i32 + %7 = load i32, i32* @b, align 4, !tbaa !8 + %tobool24 = icmp eq i32 %7, 0 + br i1 %tobool24, label %if.end26, label %af + +if.end26: ; preds = %ae + %tobool27 = icmp eq i32 %q.1, 0 + %tobool30 = icmp ne i8 %p.1, 0 + %or.cond = and i1 %tobool30, %tobool27 + br i1 %or.cond, label %if.then31, label %for.inc + +if.then31: ; preds = %if.end26 + %8 = load i32, i32* @e, align 4, !tbaa !8 + %conv32 = sext i32 %8 to i64 + %call33 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i64 %conv32) + br label %for.inc + +for.inc: ; preds = %if.then13, %if.end26, %if.then31 + %l.3 = phi i16 [ %l.2, %if.then31 ], [ %l.2, %if.end26 ], [ %conv6.le, %if.then13 ] + %m.2 = phi i32 [ %m.1, %if.then31 ], [ %m.1, %if.end26 ], [ %div, %if.then13 ] + %n.2 = phi i32 [ %n.1, %if.then31 ], [ %n.1, %if.end26 ], [ %n.0, %if.then13 ] + %i.2 = phi i32 [ %i.1, %if.then31 ], [ %i.1, %if.end26 ], [ %i.0, %if.then13 ] + %o.1 = phi i32 [ %conv23, %if.then31 ], [ %conv23, %if.end26 ], [ %o.0, %if.then13 ] + %p.2 = phi i8 [ %p.1, %if.then31 ], [ %p.1, %if.end26 ], [ undef, %if.then13 ] + %k.2 = phi i8 [ %k.1, %if.then31 ], [ %k.1, %if.end26 ], [ %conv3, %if.then13 ] + %q.2 = phi i32 [ 0, %if.then31 ], [ %q.1, %if.end26 ], [ %q.0, %if.then13 ] + %9 = load i32, i32* @h, align 4, !tbaa !8 + %inc = add nsw i32 %9, 1 + store i32 %inc, i32* @h, align 4, !tbaa !8 + br label %for.cond + +for.cond35: ; preds = %if.then, %if.then13, %for.inc44 + %l.5 = phi i16 [ %l.6, %for.inc44 ], [ %l.0, %if.then ], [ %conv6.le, %if.then13 ] + %m.4 = phi i32 [ %m.5, %for.inc44 ], [ %m.0, %if.then ], [ %div, %if.then13 ] + %n.3 = phi i32 [ %n.4, %for.inc44 ], [ %n.0, %if.then ], [ %n.0, %if.then13 ] + %i.3 = phi i32 [ %inc45, %for.inc44 ], [ %i.0, %if.then ], [ %i.0, %if.then13 ] + %o.2 = phi i32 [ %o.3, %for.inc44 ], [ %o.0, %if.then ], [ %o.0, %if.then13 ] + %p.4 = phi i8 [ %p.5, %for.inc44 ], [ %p.0, %if.then ], [ %k.0, %if.then13 ] + %k.4 = phi i8 [ %k.5, %for.inc44 ], [ %k.0, %if.then ], [ %conv3, %if.then13 ] + %q.3 = phi i32 [ %q.4, %for.inc44 ], [ %q.0, %if.then ], [ %q.0, %if.then13 ] + %tobool36 = icmp eq i32 %i.3, 0 + br i1 %tobool36, label %for.end46, label %af + +af: ; preds = %for.cond35, %ae + %l.6 = phi i16 [ %l.5, %for.cond35 ], [ %l.2, %ae ] + %m.5 = phi i32 [ %m.4, %for.cond35 ], [ %m.1, %ae ] + %n.4 = phi i32 [ %n.3, %for.cond35 ], [ %n.1, %ae ] + %i.4 = phi i32 [ %i.3, %for.cond35 ], [ %i.1, %ae ] + %o.3 = phi i32 [ %o.2, %for.cond35 ], [ %conv23, %ae ] + %p.5 = phi i8 [ %p.4, %for.cond35 ], [ %p.1, %ae ] + %k.5 = phi i8 [ %k.4, %for.cond35 ], [ %k.1, %ae ] + %q.4 = phi i32 [ %q.3, %for.cond35 ], [ %q.1, %ae ] + %10 = load i8, i8* @c, align 1, !tbaa !3 + %tobool37 = icmp eq i8 %10, 0 + br i1 %tobool37, label %if.end39, label %for.inc44 + +if.end39: ; preds = %af + %tobool40 = icmp eq i32 %o.3, 0 + br i1 %tobool40, label %for.end46, label %if.then41 + +if.then41: ; preds = %if.end39 + %call42 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), i64 ptrtoint (void ()* @fn to i64)) + br label %for.end46 + +for.inc44: ; preds = %af + %inc45 = add nsw i32 %i.4, 1 + br label %for.cond35 + +for.end46: ; preds = %for.cond35, %if.end39, %if.then41 + %l.7 = phi i16 [ %l.6, %if.then41 ], [ %l.6, %if.end39 ], [ %l.5, %for.cond35 ] + %m.6 = phi i32 [ %m.5, %if.then41 ], [ %m.5, %if.end39 ], [ %m.4, %for.cond35 ] + %n.5 = phi i32 [ %n.4, %if.then41 ], [ %n.4, %if.end39 ], [ %n.3, %for.cond35 ] + %i.5 = phi i32 [ %i.4, %if.then41 ], [ %i.4, %if.end39 ], [ 0, %for.cond35 ] + %p.6 = phi i8 [ %p.5, %if.then41 ], [ %p.5, %if.end39 ], [ %p.4, %for.cond35 ] + %k.6 = phi i8 [ %k.5, %if.then41 ], [ %k.5, %if.end39 ], [ %k.4, %for.cond35 ] + %q.5 = phi i32 [ %q.4, %if.then41 ], [ %q.4, %if.end39 ], [ %q.3, %for.cond35 ] + %tobool50 = icmp eq i32 %m.6, 0 + br label %for.cond47 + +for.cond47: ; preds = %for.cond47, %for.end46 + %n.7 = phi i32 [ %n.5, %for.end46 ], [ %.mux, %for.cond47 ] + %tobool48 = icmp eq i32 %n.7, 0 + %brmerge = or i1 %tobool48, %tobool50 + %.mux = select i1 %tobool48, i32 0, i32 9 + br i1 %brmerge, label %for.cond47, label %ae +} + +; Function Attrs: nounwind +declare dso_local i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #1 + +attributes #0 = { noreturn nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"NumRegisterParameters", i32 0} +!1 = !{i32 1, !"wchar_size", i32 4} +!2 = !{!"clang version 8.0.0 "} +!3 = !{!4, !4, i64 0} +!4 = !{!"omnipotent char", !5, i64 0} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7, !7, i64 0} +!7 = !{!"long long", !4, i64 0} +!8 = !{!9, !9, i64 0} +!9 = !{!"int", !4, i64 0} +!10 = !{!11, !11, i64 0} +!11 = !{!"short", !4, i64 0}