From 9cd163281490dd5de4597cc184e7e15f658acea0 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 5 Aug 2009 07:05:41 +0000 Subject: [PATCH] Another nasty coalescer bug (is there another kind): After coalescing reg1027's def and kill are both at the same point: %reg1027,0.000000e+00 = [56,814:0) 0@70-(814) bb5: 60 %reg1027 = t2MOVr %reg1027, 14, %reg0, %reg0 68 %reg1027 = t2LDRi12 %reg1027, 8, 14, %reg0 76 t2CMPzri %reg1038, 0, 14, %reg0, %CPSR 84 %reg1027 = t2MOVr %reg1027, 14, %reg0, %reg0 96 t2Bcc mbb, 1, %CPSR Do not remove the kill marker on t2LDRi12. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78178 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SimpleRegisterCoalescing.cpp | 24 ++- .../CodeGen/Thumb2/2009-08-04-CoalescerBug.ll | 153 ++++++++++++++++++ 2 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/Thumb2/2009-08-04-CoalescerBug.ll diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index a2d521b139a..08e0bcf85b6 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -804,12 +804,26 @@ void SimpleRegisterCoalescing::RemoveUnnecessaryKills(unsigned Reg, for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg), UE = mri_->use_end(); UI != UE; ++UI) { MachineOperand &UseMO = UI.getOperand(); - if (UseMO.isKill()) { - MachineInstr *UseMI = UseMO.getParent(); - unsigned UseIdx = li_->getUseIndex(li_->getInstructionIndex(UseMI)); - const LiveRange *UI = LI.getLiveRangeContaining(UseIdx); - if (!UI || !LI.isKill(UI->valno, UseIdx+1)) + if (!UseMO.isKill()) + continue; + MachineInstr *UseMI = UseMO.getParent(); + unsigned UseIdx = li_->getUseIndex(li_->getInstructionIndex(UseMI)); + const LiveRange *UI = LI.getLiveRangeContaining(UseIdx); + if (!UI || !LI.isKill(UI->valno, UseIdx+1)) { + if (UI->valno->def != UseIdx+1) { + // Interesting problem. After coalescing reg1027's def and kill are both + // at the same point: %reg1027,0.000000e+00 = [56,814:0) 0@70-(814) + // + // bb5: + // 60 %reg1027 = t2MOVr %reg1027, 14, %reg0, %reg0 + // 68 %reg1027 = t2LDRi12 %reg1027, 8, 14, %reg0 + // 76 t2CMPzri %reg1038, 0, 14, %reg0, %CPSR + // 84 %reg1027 = t2MOVr %reg1027, 14, %reg0, %reg0 + // 96 t2Bcc mbb, 1, %CPSR + // + // Do not remove the kill marker on t2LDRi12. UseMO.setIsKill(false); + } } } } diff --git a/test/CodeGen/Thumb2/2009-08-04-CoalescerBug.ll b/test/CodeGen/Thumb2/2009-08-04-CoalescerBug.ll new file mode 100644 index 00000000000..55e24df5d33 --- /dev/null +++ b/test/CodeGen/Thumb2/2009-08-04-CoalescerBug.ll @@ -0,0 +1,153 @@ +; RUN: llvm-as < %s | llc -mtriple=thumbv7-apple-darwin -mattr=+neon,+neonfp -relocation-model=pic -disable-fp-elim + + type { %struct.GAP } ; type %0 + type { i16, i8, i8 } ; type %1 + type { [2 x i32], [2 x i32] } ; type %2 + type { %struct.rec* } ; type %3 + type { i8, i8, i16, i8, i8, i8, i8 } ; type %4 + %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } + %struct.FILE_POS = type { i8, i8, i16, i32 } + %struct.FIRST_UNION = type { %struct.FILE_POS } + %struct.FOURTH_UNION = type { %struct.STYLE } + %struct.GAP = type { i8, i8, i16 } + %struct.LIST = type { %struct.rec*, %struct.rec* } + %struct.SECOND_UNION = type { %1 } + %struct.STYLE = type { %0, %0, i16, i16, i32 } + %struct.THIRD_UNION = type { %2 } + %struct.__sFILEX = type opaque + %struct.__sbuf = type { i8*, i32 } + %struct.head_type = type { [2 x %struct.LIST], %struct.FIRST_UNION, %struct.SECOND_UNION, %struct.THIRD_UNION, %struct.FOURTH_UNION, %struct.rec*, %3, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, i32 } + %struct.rec = type { %struct.head_type } +@.str24239 = external constant [20 x i8], align 1 ; <[20 x i8]*> [#uses=1] +@no_file_pos = external global %4 ; <%4*> [#uses=1] +@zz_tmp = external global %struct.rec* ; <%struct.rec**> [#uses=1] +@.str81872 = external constant [10 x i8], align 1 ; <[10 x i8]*> [#uses=1] +@out_fp = external global %struct.FILE* ; <%struct.FILE**> [#uses=2] +@cpexists = external global i32 ; [#uses=2] +@.str212784 = external constant [17 x i8], align 1 ; <[17 x i8]*> [#uses=1] +@.str1822946 = external constant [8 x i8], align 1 ; <[8 x i8]*> [#uses=1] +@.str1842948 = external constant [11 x i8], align 1 ; <[11 x i8]*> [#uses=1] + +declare arm_apcscc i32 @fprintf(%struct.FILE* nocapture, i8* nocapture, ...) nounwind + +declare arm_apcscc i32 @"\01_fwrite"(i8*, i32, i32, i8*) + +declare arm_apcscc %struct.FILE* @OpenIncGraphicFile(i8*, i8 zeroext, %struct.rec** nocapture, %struct.FILE_POS*, i32* nocapture) nounwind + +declare arm_apcscc void @Error(i32, i32, i8*, i32, %struct.FILE_POS*, ...) nounwind + +declare arm_apcscc i8* @fgets(i8*, i32, %struct.FILE* nocapture) nounwind + +define arm_apcscc void @PS_PrintGraphicInclude(%struct.rec* %x, i32 %colmark, i32 %rowmark) nounwind { +entry: + br label %bb5 + +bb5: ; preds = %bb5, %entry + %.pn = phi %struct.rec* [ %y.0, %bb5 ], [ undef, %entry ] ; <%struct.rec*> [#uses=1] + %y.0.in = getelementptr %struct.rec* %.pn, i32 0, i32 0, i32 0, i32 1, i32 0 ; <%struct.rec**> [#uses=1] + %y.0 = load %struct.rec** %y.0.in ; <%struct.rec*> [#uses=2] + br i1 undef, label %bb5, label %bb6 + +bb6: ; preds = %bb5 + %0 = call arm_apcscc %struct.FILE* @OpenIncGraphicFile(i8* undef, i8 zeroext 0, %struct.rec** undef, %struct.FILE_POS* null, i32* undef) nounwind ; <%struct.FILE*> [#uses=1] + br i1 false, label %bb.i, label %FontHalfXHeight.exit + +bb.i: ; preds = %bb6 + br label %FontHalfXHeight.exit + +FontHalfXHeight.exit: ; preds = %bb.i, %bb6 + br i1 undef, label %bb.i1, label %FontSize.exit + +bb.i1: ; preds = %FontHalfXHeight.exit + br label %FontSize.exit + +FontSize.exit: ; preds = %bb.i1, %FontHalfXHeight.exit + %1 = load i32* undef, align 4 ; [#uses=1] + %2 = icmp ult i32 0, undef ; [#uses=1] + br i1 %2, label %bb.i5, label %FontName.exit + +bb.i5: ; preds = %FontSize.exit + call arm_apcscc void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 1, i32 2, i8* getelementptr ([20 x i8]* @.str24239, i32 0, i32 0), i32 0, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*), i8* getelementptr ([10 x i8]* @.str81872, i32 0, i32 0)) nounwind + br label %FontName.exit + +FontName.exit: ; preds = %bb.i5, %FontSize.exit + %3 = call arm_apcscc i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* undef, i8* getelementptr ([8 x i8]* @.str1822946, i32 0, i32 0), i32 %1, i8* undef) nounwind ; [#uses=0] + %4 = call arm_apcscc i32 @"\01_fwrite"(i8* getelementptr ([11 x i8]* @.str1842948, i32 0, i32 0), i32 1, i32 10, i8* undef) nounwind ; [#uses=0] + %5 = sub i32 %colmark, undef ; [#uses=1] + %6 = sub i32 %rowmark, undef ; [#uses=1] + %7 = load %struct.FILE** @out_fp, align 4 ; <%struct.FILE*> [#uses=1] + %8 = call arm_apcscc i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* %7, i8* getelementptr ([17 x i8]* @.str212784, i32 0, i32 0), i32 %5, i32 %6) nounwind ; [#uses=0] + store i32 0, i32* @cpexists, align 4 + %9 = getelementptr %struct.rec* %y.0, i32 0, i32 0, i32 3, i32 0, i32 0, i32 1 ; [#uses=1] + %10 = load i32* %9, align 4 ; [#uses=1] + %11 = sub i32 0, %10 ; [#uses=1] + %12 = load %struct.FILE** @out_fp, align 4 ; <%struct.FILE*> [#uses=1] + %13 = call arm_apcscc i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* %12, i8* getelementptr ([17 x i8]* @.str212784, i32 0, i32 0), i32 undef, i32 %11) nounwind ; [#uses=0] + store i32 0, i32* @cpexists, align 4 + br label %bb100.outer.outer + +bb100.outer.outer: ; preds = %bb79.critedge, %bb1.i3, %FontName.exit + %x_addr.0.ph.ph = phi %struct.rec* [ %x, %FontName.exit ], [ null, %bb79.critedge ], [ null, %bb1.i3 ] ; <%struct.rec*> [#uses=1] + %14 = getelementptr %struct.rec* %x_addr.0.ph.ph, i32 0, i32 0, i32 1, i32 0 ; <%struct.FILE_POS*> [#uses=0] + br label %bb100.outer + +bb.i80: ; preds = %bb3.i85 + br i1 undef, label %bb2.i84, label %bb2.i51 + +bb2.i84: ; preds = %bb100.outer, %bb.i80 + br i1 undef, label %bb3.i77, label %bb3.i85 + +bb3.i85: ; preds = %bb2.i84 + br i1 false, label %StringBeginsWith.exit88, label %bb.i80 + +StringBeginsWith.exit88: ; preds = %bb3.i85 + br i1 undef, label %bb3.i77, label %bb2.i51 + +bb2.i.i68: ; preds = %bb3.i77 + br label %bb3.i77 + +bb3.i77: ; preds = %bb2.i.i68, %StringBeginsWith.exit88, %bb2.i84 + br i1 false, label %bb1.i58, label %bb2.i.i68 + +bb1.i58: ; preds = %bb3.i77 + unreachable + +bb.i47: ; preds = %bb3.i52 + br i1 undef, label %bb2.i51, label %bb2.i.i15.critedge + +bb2.i51: ; preds = %bb.i47, %StringBeginsWith.exit88, %bb.i80 + %15 = load i8* undef, align 1 ; [#uses=0] + br i1 false, label %StringBeginsWith.exit55thread-split, label %bb3.i52 + +bb3.i52: ; preds = %bb2.i51 + br i1 false, label %StringBeginsWith.exit55, label %bb.i47 + +StringBeginsWith.exit55thread-split: ; preds = %bb2.i51 + br label %StringBeginsWith.exit55 + +StringBeginsWith.exit55: ; preds = %StringBeginsWith.exit55thread-split, %bb3.i52 + br label %bb2.i41 + +bb2.i41: ; preds = %bb2.i41, %StringBeginsWith.exit55 + br label %bb2.i41 + +bb2.i.i15.critedge: ; preds = %bb.i47 + %16 = call arm_apcscc i8* @fgets(i8* undef, i32 512, %struct.FILE* %0) nounwind ; [#uses=0] + %iftmp.560.0 = select i1 undef, i32 2, i32 0 ; [#uses=1] + br label %bb100.outer + +bb2.i8: ; preds = %bb100.outer + br i1 undef, label %bb1.i3, label %bb79.critedge + +bb1.i3: ; preds = %bb2.i8 + br label %bb100.outer.outer + +bb79.critedge: ; preds = %bb2.i8 + store %struct.rec* null, %struct.rec** @zz_tmp, align 4 + br label %bb100.outer.outer + +bb100.outer: ; preds = %bb2.i.i15.critedge, %bb100.outer.outer + %state.0.ph = phi i32 [ 0, %bb100.outer.outer ], [ %iftmp.560.0, %bb2.i.i15.critedge ] ; [#uses=1] + %cond = icmp eq i32 %state.0.ph, 1 ; [#uses=1] + br i1 %cond, label %bb2.i8, label %bb2.i84 +}