Index: llvm/lib/CodeGen/PHIElimination.cpp =================================================================== --- llvm/lib/CodeGen/PHIElimination.cpp +++ llvm/lib/CodeGen/PHIElimination.cpp @@ -206,7 +206,18 @@ if (MBB.empty() || !MBB.front().isPHI()) return false; // Quick exit for basic blocks without PHIs. - // Get an iterator to the last PHI node. + // Get an iterator to the last PHI node or LABEL instruction. + // LastPHIIt - Fix PR16508: + // When phis get lowered, destination copies are inserted using an iterator that is + // determined once for all phis in the block, which BuildMI interprets as a request + // to insert an instruction directly before the iterator. In the case of a cyclic + // phi, source copies may also be inserted directly before this iterator, which can + // cause source copies to be inserted before destination copies. The fix is to keep + // an iterator to the last phi and then advance it while lowering each phi in order + // to insert destination copies directly after the phis. + // SkipPHIsAndLabels - Copies need to be inserted after phi nodes and + // also after any exception handling labels: in landing pads execution + // starts at the label, so any copies placed before it won't be executed! MachineBasicBlock::iterator LastPHIIt = std::prev(MBB.SkipPHIsAndLabels(MBB.begin())); Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -932,7 +932,17 @@ // Insert all the dbg_values which have not already been inserted in source // order sequence. if (HasDbg) { - MachineBasicBlock::iterator BBBegin = BB->getFirstNonPHI(); + // Get first NonPHI and NonLabels, insert dbg_values after both. + // Deal with DBG_VALUEs, which are a bit tricky: + // PHI + // DBG_VALUE + // LABEL + // and the DBG_VALUE will break PHI elimination when lower after Label, + // Here the DBG_VALUE needs to moving after the labels, like this: + // PHI + // LABEL + // DBG_VALUE + MachineBasicBlock::iterator BBBegin = BB->SkipPHIsAndLabels(BB->begin()); // Sort the source order instructions and use the order to insert debug // values. Use stable_sort so that DBG_VALUEs are inserted in the same order Index: llvm/test/CodeGen/X86/dbg-changes-codegen-phi-elimination.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/dbg-changes-codegen-phi-elimination.ll @@ -0,0 +1,74 @@ +; RUN: llc -O0 %s -mtriple=x86_64 -stop-after=phi-node-elimination -o - | FileCheck %s + +; If there is the dbg_values between phi and label (after phi and before label), +; dbg_values will block PHI to lower after LABELs. To fix this issue, insert +; all dbg_values after Labels in the function ScheduleDAGSDNodes::EmitSchedule, +; Moving dbg_value in the first place to avoid dbg_value impact PHI lowering. +; Fix the issue: https://bugs.llvm.org/show_bug.cgi?id=43859 + +; The purpose of this case is to check two items: +; 1. reorder dbg_value and insert after label +; 2. phi could lowering after Labels +; before: +; phi +; dbg_value +; label +; after: +; LABEL +; COPY +; DBG_VALUE + +define i32 @func(i32 %a0) personality void ()* @personality { +bb1: + %v = icmp slt i32 %a0, 0 + br i1 %v, label %bb2, label %bb3 + +bb2: + br label %bb3 + +bb3: +; CHECK: bb.2.bb3: +; CHECK: EH_LABEL +; CHECK-NEXT: %0:gr32 = COPY %7 +; CHECK-NEXT: DBG_VALUE %0 + %0 = phi i32 [ 2, %bb2 ], [ 1, %bb1 ] + call void @llvm.dbg.value(metadata i32 %0, metadata !8, metadata !DIExpression()), !dbg !13 + invoke void @foo() to label %end unwind label %lpad + +end: + ret i32 %0 + +lpad: + %1 = landingpad { i8*, i32 } + cleanup + unreachable +} + +declare void @foo() + +declare void @personality() + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #0 + +attributes #0 = { nounwind readnone speculatable willreturn } +attributes #1 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "a.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{i32 1, !"min_enum_size", i32 4} +!7 = !{!"clang"} +!8 = !DILocalVariable(name: "c", scope: !9, file: !1, line: 3, type: !12) +!9 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !10, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) +!10 = !DISubroutineType(types: !11) +!11 = !{!12, !12} +!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 3, column: 13, scope: !9)