Index: lib/CodeGen/TailDuplicator.cpp =================================================================== --- lib/CodeGen/TailDuplicator.cpp +++ lib/CodeGen/TailDuplicator.cpp @@ -592,6 +592,14 @@ } } + // If the block to be duplicated ends in an unanalyzable fallthrough, don't + // duplicate it. + MachineBasicBlock *PredTBB = nullptr, *PredFBB = nullptr; + SmallVector PredCond; + if (TII->AnalyzeBranch(TailBB, PredTBB, PredFBB, PredCond, true) + && TailBB.canFallThrough()) + return false; + if (HasIndirectbr && PreRegAlloc) return true; Index: test/CodeGen/PowerPC/tail-dup-analyzable-fallthrough.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/tail-dup-analyzable-fallthrough.ll @@ -0,0 +1,68 @@ +; RUN: llc -O2 < %s | FileCheck %s +target datalayout = "e-m:e-i64:64-n32:64" +target triple = "powerpc64le--linux-gnu" + +%struct.HashBucket = type { %struct.HashBucket*, i64, i64* } +; CHECK: divdu +; CHECK: mulld +; CHECK: sub +; CHECK: b [[LOOPENTRY:[._0-9A-Za-z]+]] +; CHECK: [[LOOPTOP:[._0-9A-Za-z]+]]: +; CHECK-NOT: {{{[._0-9A-Za-z]+}}}: +; CHECK: ld [[PTRREG:[0-9]+]], 0([[PTRREG]]) +; CHECK-NEXT: [[LOOPENTRY]]: +; CHECK-NOT: {{{[._0-9A-Za-z]+}}}: +; CHECK: cmpldi [[PTRREG]], 0 +; CHECK-NEXT: beqlr +; Function Attrs: norecurse nounwind readonly +define i64* @findKey(%struct.HashBucket** nocapture readonly %Buckets, i64 %BucketSize, i64 %Key) #0 { +entry: + %mul.i = mul i64 %Key, 237 + %shr.i = lshr i64 %mul.i, 16 + %xor.i = xor i64 %shr.i, %Key + %rem = urem i64 %xor.i, %BucketSize + %arrayidx = getelementptr inbounds %struct.HashBucket*, %struct.HashBucket** %Buckets, i64 %rem + %current.012 = load %struct.HashBucket*, %struct.HashBucket** %arrayidx, align 8, !tbaa !1 + %tobool13 = icmp eq %struct.HashBucket* %current.012, null + br i1 %tobool13, label %cond.end, label %land.rhs.preheader + +land.rhs.preheader: ; preds = %entry + br label %land.rhs + +land.rhs: ; preds = %land.rhs.preheader, %for.inc + %current.014 = phi %struct.HashBucket* [ %current.0, %for.inc ], [ %current.012, %land.rhs.preheader ] + %Key1 = getelementptr inbounds %struct.HashBucket, %struct.HashBucket* %current.014, i64 0, i32 1 + %0 = load i64, i64* %Key1, align 8, !tbaa !5 + %lnot = icmp eq i64 %0, %Key + br i1 %lnot, label %cond.true, label %for.inc + +for.inc: ; preds = %land.rhs + %Next = getelementptr inbounds %struct.HashBucket, %struct.HashBucket* %current.014, i64 0, i32 0 + %current.0 = load %struct.HashBucket*, %struct.HashBucket** %Next, align 8, !tbaa !1 + %tobool = icmp eq %struct.HashBucket* %current.0, null + br i1 %tobool, label %cond.end.loopexit, label %land.rhs + +cond.true: ; preds = %land.rhs + %current.014.lcssa = phi %struct.HashBucket* [ %current.014, %land.rhs ] + %Value = getelementptr inbounds %struct.HashBucket, %struct.HashBucket* %current.014.lcssa, i64 0, i32 2 + %1 = load i64*, i64** %Value, align 8, !tbaa !8 + br label %cond.end + +cond.end.loopexit: ; preds = %for.inc + br label %cond.end + +cond.end: ; preds = %cond.end.loopexit, %entry, %cond.true + %cond = phi i64* [ %1, %cond.true ], [ null, %entry ], [ null, %cond.end.loopexit ] + ret i64* %cond +} + +attributes #0 = { norecurse nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pwr8" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+power8-vector,+vsx,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!1 = !{!2, !2, i64 0} +!2 = !{!"any pointer", !3, i64 0} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C/C++ TBAA"} +!5 = !{!6, !7, i64 8} +!6 = !{!"HashBucket", !2, i64 0, !7, i64 8, !2, i64 16} +!7 = !{!"long long", !3, i64 0} +!8 = !{!6, !2, i64 16}