Index: lib/CodeGen/PeepholeOptimizer.cpp =================================================================== --- lib/CodeGen/PeepholeOptimizer.cpp +++ lib/CodeGen/PeepholeOptimizer.cpp @@ -1,4 +1,3 @@ -//===-- PeepholeOptimizer.cpp - Peephole Optimizations --------------------===// // // The LLVM Compiler Infrastructure // @@ -505,12 +504,13 @@ return false; unsigned Reg = MI->getOperand(0).getReg(); - // To reduce compilation time, we check MRI->hasOneUse when inserting + // To reduce compilation time, we check MRI->hasOneNonDBGUse when inserting // loads. It should be checked when processing uses of the load, since // uses can be removed during peephole. if (!MI->getOperand(0).getSubReg() && TargetRegisterInfo::isVirtualRegister(Reg) && - MRI->hasOneUse(Reg)) { + // Only count NonDBG uses. + MRI->hasOneNonDBGUse(Reg)) { FoldAsLoadDefReg = Reg; return true; } @@ -594,10 +594,14 @@ ++MII; LocalMIs.insert(MI); + // Skip debug values. They should not effect this peephole optimization. + if (MI->isDebugValue()) + continue; + // If there exists an instruction which belongs to the following // categories, we will discard the load candidate. if (MI->isLabel() || MI->isPHI() || MI->isImplicitDef() || - MI->isKill() || MI->isInlineAsm() || MI->isDebugValue() || + MI->isKill() || MI->isInlineAsm() || MI->hasUnmodeledSideEffects()) { FoldAsLoadDefReg = 0; continue; @@ -633,6 +637,7 @@ if (!isLoadFoldable(MI, FoldAsLoadDefReg) && FoldAsLoadDefReg) { // We need to fold load after optimizeCmpInstr, since optimizeCmpInstr // can enable folding by converting SUB to CMP. + unsigned FoldedReg = FoldAsLoadDefReg; // Need this below MachineInstr *DefMI = 0; MachineInstr *FoldMI = TII->optimizeLoadInstr(MI, MRI, FoldAsLoadDefReg, DefMI); @@ -649,6 +654,18 @@ // MI is replaced with FoldMI. Changed = true; + + // Mark any DBG_VALUE that uses FoldReg as undef (but don't + // delete it.) Code copied from DeadMachineInstructionElim. + MachineRegisterInfo::use_iterator nextI; + for (MachineRegisterInfo::use_iterator I = MRI->use_begin(FoldedReg), + E = MRI->use_end(); I!=E; I=nextI) { + nextI = llvm::next(I); // I is invalidated by the setReg + MachineOperand& Use = I.getOperand(); + MachineInstr *UseMI = Use.getParent(); + if (UseMI->isDebugValue()) + UseMI->getOperand(0).setReg(0U); + } continue; } } Index: test/CodeGen/X86/dbg-changes-codegen-1.ll =================================================================== --- test/CodeGen/X86/dbg-changes-codegen-1.ll +++ test/CodeGen/X86/dbg-changes-codegen-1.ll @@ -0,0 +1,74 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; The Peephole optimizer should fold the load into the cmp even with debug info. +; CHECK-NOT: cmpq {{%[a-z]+}}, {{%[a-z]+}} +; CHECK: cmpq {{%[a-z]+}}, wibble(%rip) + +; The following bitcode was generated with: +; clang -emit-llvm -S -O2 -g +; from this source: +; struct Foo { +; bool bar(); +; bool operator==(Foo &baz) { return (this == &baz); } +; }; +; Foo *wibble; +; bool Foo::bar() { return (*this == *wibble); } + +%struct.Foo = type { i8 } + +@wibble = global %struct.Foo* null, align 8 + +; Function Attrs: nounwind readonly uwtable +define zeroext i1 @_ZN3Foo3barEv(%struct.Foo* %this) #0 align 2 { +entry: + tail call void @llvm.dbg.value(metadata !{%struct.Foo* %this}, i64 0, metadata !19), !dbg !28 + %0 = load %struct.Foo** @wibble, align 8, !dbg !28, !tbaa !29 + tail call void @llvm.dbg.value(metadata !{%struct.Foo* %this}, i64 0, metadata !32), !dbg !33 + tail call void @llvm.dbg.value(metadata !{%struct.Foo* %0}, i64 0, metadata !34), !dbg !33 + %cmp.i = icmp eq %struct.Foo* %0, %this, !dbg !33 + ret i1 %cmp.i, !dbg !28 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata) #1 + +attributes #0 = { nounwind readonly uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.3 (PS4 clang version 9.99.0.1568 debug)", i1 true, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !26, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/trevor/orbis/dev2/toolchain/bugs/z57520/greg0.cpp] [DW_LANG_C_plus_plus] +!1 = metadata !{metadata !"test.cpp", metadata !"/home/kromanova"} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4, metadata !22} +!4 = metadata !{i32 786478, metadata !1, null, metadata !"bar", metadata !"bar", metadata !"_ZN3Foo3barEv", i32 6, metadata !5, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, i1 (%struct.Foo*)* @_ZN3Foo3barEv, null, metadata !11, metadata !18, i32 6} ; [ DW_TAG_subprogram ] [line 6] [def] [bar] +!5 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !6, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!6 = metadata !{metadata !7, metadata !8} +!7 = metadata !{i32 786468, null, null, metadata !"bool", i32 0, i64 8, i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ] [bool] [line 0, size 8, align 8, offset 0, enc DW_ATE_boolean] +!8 = metadata !{i32 786447, i32 0, i32 0, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from Foo] +!9 = metadata !{i32 786451, metadata !1, null, metadata !"Foo", i32 1, i64 8, i64 8, i32 0, i32 0, null, metadata !10, i32 0, null, null} ; [ DW_TAG_structure_type ] [Foo] [line 1, size 8, align 8, offset 0] [from ] +!10 = metadata !{metadata !11, metadata !13} +!11 = metadata !{i32 786478, metadata !1, metadata !9, metadata !"bar", metadata !"bar", metadata !"_ZN3Foo3barEv", i32 2, metadata !5, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null, i32 0, metadata !12, i32 2} ; [ DW_TAG_subprogram ] [line 2] [bar] +!12 = metadata !{i32 786468} +!13 = metadata !{i32 786478, metadata !1, metadata !9, metadata !"operator==", metadata !"operator==", metadata !"_ZN3FooeqERS_", i32 3, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null, i32 0, metadata !17, i32 3} ; [ DW_TAG_subprogram ] [line 3] [operator==] +!14 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !15, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!15 = metadata !{metadata !7, metadata !8, metadata !16} +!16 = metadata !{i32 786448, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !9} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from Foo] +!17 = metadata !{i32 786468} +!18 = metadata !{metadata !19} +!19 = metadata !{i32 786689, metadata !4, metadata !"this", metadata !20, i32 16777222, metadata !21, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 6] +!20 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/home/kromanova/test.cpp] +!21 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from Foo] +!22 = metadata !{i32 786478, metadata !1, null, metadata !"operator==", metadata !"operator==", metadata !"_ZN3FooeqERS_", i32 3, metadata !14, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, null, null, metadata !13, metadata !23, i32 3} ; [ DW_TAG_subprogram ] [line 3] [def] [operator==] +!23 = metadata !{metadata !24, metadata !25} +!24 = metadata !{i32 786689, metadata !22, metadata !"this", metadata !20, i32 16777219, metadata !21, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 3] +!25 = metadata !{i32 786689, metadata !22, metadata !"baz", metadata !20, i32 33554435, metadata !16, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [baz] [line 3] +!26 = metadata !{metadata !27} +!27 = metadata !{i32 786484, i32 0, null, metadata !"wibble", metadata !"wibble", metadata !"", metadata !20, i32 5, metadata !21, i32 0, i32 1, %struct.Foo** @wibble, null} ; [ DW_TAG_variable ] [wibble] [line 5] [def] +!28 = metadata !{i32 6, i32 0, metadata !4, null} +!29 = metadata !{metadata !"any pointer", metadata !30} +!30 = metadata !{metadata !"omnipotent char", metadata !31} +!31 = metadata !{metadata !"Simple C/C++ TBAA"} +!32 = metadata !{i32 786689, metadata !22, metadata !"this", metadata !20, i32 16777219, metadata !21, i32 1088, metadata !28} ; [ DW_TAG_arg_variable ] [this] [line 3] +!33 = metadata !{i32 3, i32 0, metadata !22, metadata !28} +!34 = metadata !{i32 786689, metadata !22, metadata !"baz", metadata !20, i32 33554435, metadata !16, i32 0, metadata !28} ; [ DW_TAG_arg_variable ] [baz] [line 3] Index: test/CodeGen/X86/dbg-changes-codegen-2.ll =================================================================== --- test/CodeGen/X86/dbg-changes-codegen-2.ll +++ test/CodeGen/X86/dbg-changes-codegen-2.ll @@ -0,0 +1,102 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; The Peephole optimizer should fold the load into the cmp even with debug info. +; CHECK-NOT: cmpq {{%[a-z]+}}, {{%[a-z]+}} +; CHECK: cmpq {{%[a-z]+}}, b(%rip) + +; The following bitcode was generated with: +; clang -emit-llvm -S -O2 -g +; from this source: +; struct Wibble { +; int x; +; } *a, *b; +; struct Flibble { +; void bar(Wibble *c) { +; if (c < b) +; b = 0; +; c->x = 0; +; } +; } f; +; void baz() { f.bar(a); } + + +%struct.Wibble = type { i32 } +%struct.Flibble = type { i8 } + +@a = global %struct.Wibble* null, align 8 +@b = global %struct.Wibble* null, align 8 +@f = global %struct.Flibble zeroinitializer, align 1 + +; Function Attrs: nounwind uwtable +define void @_Z3bazv() #0 { +entry: + %0 = load %struct.Wibble** @a, align 8, !dbg !33, !tbaa !34 + tail call void @llvm.dbg.value(metadata !37, i64 0, metadata !38), !dbg !39 + tail call void @llvm.dbg.value(metadata !{%struct.Wibble* %0}, i64 0, metadata !40), !dbg !39 + %1 = load %struct.Wibble** @b, align 8, !dbg !41, !tbaa !34 + %cmp.i = icmp ugt %struct.Wibble* %1, %0, !dbg !41 + br i1 %cmp.i, label %if.then.i, label %_ZN7Flibble3barEP6Wibble.exit, !dbg !41 + +if.then.i: ; preds = %entry + store %struct.Wibble* null, %struct.Wibble** @b, align 8, !dbg !42, !tbaa !34 + br label %_ZN7Flibble3barEP6Wibble.exit, !dbg !42 + +_ZN7Flibble3barEP6Wibble.exit: ; preds = %entry, %if.then.i + %x.i = getelementptr inbounds %struct.Wibble* %0, i64 0, i32 0, !dbg !43 + store i32 0, i32* %x.i, align 4, !dbg !43, !tbaa !44 + ret void, !dbg !33 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.value(metadata, i64, metadata) #1 + +attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.3 (PS4 clang version 9.99.0.1568 debug)", i1 true, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !29, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/kromanova/test.cpp] [DW_LANG_C_plus_plus] +!1 = metadata !{metadata !"test.cpp", metadata !"/home/kromanova"} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4, metadata !8} +!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"baz", metadata !"baz", metadata !"_Z3bazv", i32 11, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, void ()* @_Z3bazv, null, null, metadata !2, i32 11} ; [ DW_TAG_subprogram ] [line 11] [def] [baz] +!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/home/kromanova/test.cpp] +!6 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!7 = metadata !{null} +!8 = metadata !{i32 786478, metadata !1, null, metadata !"bar", metadata !"bar", metadata !"_ZN7Flibble3barEP6Wibble", i32 5, metadata !9, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, null, null, metadata !14, metadata !25, i32 5} ; [ DW_TAG_subprogram ] [line 5] [def] [bar] +!9 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !10, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!10 = metadata !{null, metadata !11, metadata !20} +!11 = metadata !{i32 786447, i32 0, i32 0, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !12} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from Flibble] +!12 = metadata !{i32 786451, metadata !1, null, metadata !"Flibble", i32 4, i64 8, i64 8, i32 0, i32 0, null, metadata !13, i32 0, null, null} ; [ DW_TAG_structure_type ] [Flibble] [line 4, size 8, align 8, offset 0] [from ] +!13 = metadata !{metadata !14, metadata !16} +!14 = metadata !{i32 786478, metadata !1, metadata !12, metadata !"bar", metadata !"bar", metadata !"_ZN7Flibble3barEP6Wibble", i32 5, metadata !9, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 true, null, null, i32 0, metadata !15, i32 5} ; [ DW_TAG_subprogram ] [line 5] [bar] +!15 = metadata !{i32 786468} +!16 = metadata !{i32 786478, metadata !1, metadata !12, metadata !"Flibble", metadata !"Flibble", metadata !"", i32 4, metadata !17, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 true, null, null, i32 0, metadata !19, i32 4} ; [ DW_TAG_subprogram ] [line 4] [Flibble] +!17 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !18, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!18 = metadata !{null, metadata !11} +!19 = metadata !{i32 786468} +!20 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !21} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from Wibble] +!21 = metadata !{i32 786451, metadata !1, null, metadata !"Wibble", i32 1, i64 32, i64 32, i32 0, i32 0, null, metadata !22, i32 0, null, null} ; [ DW_TAG_structure_type ] [Wibble] [line 1, size 32, align 32, offset 0] [from ] +!22 = metadata !{metadata !23} +!23 = metadata !{i32 786445, metadata !1, metadata !21, metadata !"x", i32 2, i64 32, i64 32, i64 0, i32 0, metadata !24} ; [ DW_TAG_member ] [x] [line 2, size 32, align 32, offset 0] [from int] +!24 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!25 = metadata !{metadata !26, metadata !28} +!26 = metadata !{i32 786689, metadata !8, metadata !"this", metadata !5, i32 16777221, metadata !27, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 5] +!27 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !12} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from Flibble] +!28 = metadata !{i32 786689, metadata !8, metadata !"c", metadata !5, i32 33554437, metadata !20, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [c] [line 5] +!29 = metadata !{metadata !30, metadata !31, metadata !32} +!30 = metadata !{i32 786484, i32 0, null, metadata !"a", metadata !"a", metadata !"", metadata !5, i32 3, metadata !20, i32 0, i32 1, %struct.Wibble** @a, null} ; [ DW_TAG_variable ] [a] [line 3] [def] +!31 = metadata !{i32 786484, i32 0, null, metadata !"b", metadata !"b", metadata !"", metadata !5, i32 3, metadata !20, i32 0, i32 1, %struct.Wibble** @b, null} ; [ DW_TAG_variable ] [b] [line 3] [def] +!32 = metadata !{i32 786484, i32 0, null, metadata !"f", metadata !"f", metadata !"", metadata !5, i32 10, metadata !12, i32 0, i32 1, %struct.Flibble* @f, null} ; [ DW_TAG_variable ] [f] [line 10] [def] +!33 = metadata !{i32 11, i32 0, metadata !4, null} +!34 = metadata !{metadata !"any pointer", metadata !35} +!35 = metadata !{metadata !"omnipotent char", metadata !36} +!36 = metadata !{metadata !"Simple C/C++ TBAA"} +!37 = metadata !{%struct.Flibble* undef} +!38 = metadata !{i32 786689, metadata !8, metadata !"this", metadata !5, i32 16777221, metadata !27, i32 1088, metadata !33} ; [ DW_TAG_arg_variable ] [this] [line 5] +!39 = metadata !{i32 5, i32 0, metadata !8, metadata !33} +!40 = metadata !{i32 786689, metadata !8, metadata !"c", metadata !5, i32 33554437, metadata !20, i32 0, metadata !33} ; [ DW_TAG_arg_variable ] [c] [line 5] +!41 = metadata !{i32 6, i32 0, metadata !8, metadata !33} +!42 = metadata !{i32 7, i32 0, metadata !8, metadata !33} +!43 = metadata !{i32 8, i32 0, metadata !8, metadata !33} +!44 = metadata !{metadata !"int", metadata !35}