Index: llvm/lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- llvm/lib/CodeGen/RegisterCoalescer.cpp +++ llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -2795,10 +2795,15 @@ // // When it happens, treat that IMPLICIT_DEF as a normal value, and don't try // to erase the IMPLICIT_DEF instruction. + // + // Additionally we must keep an IMPLICIT_DEF if we're redefining an incoming + // value. + MachineInstr *OtherImpDef = Indexes->getInstructionFromIndex(V.OtherVNI->def); MachineBasicBlock *OtherMBB = OtherImpDef->getParent(); - if (DefMI && DefMI->getParent() != OtherMBB) { + if (DefMI && + (DefMI->getParent() != OtherMBB || LIS->isLiveInToMBB(LR, OtherMBB))) { LLVM_DEBUG(dbgs() << "IMPLICIT_DEF defined at " << V.OtherVNI->def << " extends into " << printMBBReference(*DefMI->getParent()) Index: llvm/test/CodeGen/X86/pr38795-verifier-error-pr38788.ll =================================================================== --- llvm/test/CodeGen/X86/pr38795-verifier-error-pr38788.ll +++ /dev/null @@ -1,36 +0,0 @@ -; RUN: llc -mtriple=i386-unknown-linux-gnu -o - -verify-machineinstrs %s | FileCheck %s - -define void @fn(i1 %cmp11) { -entry: - br label %for.cond - -for.cond: ; preds = %for.inc, %entry - %p.0 = phi i8 [ 0, %entry ], [ %p.2, %for.inc ] - %k.0 = phi i8 [ 0, %entry ], [ %k.2, %for.inc ] - br i1 %cmp11, label %for.cond35, label %if.end - -if.end: ; preds = %for.cond - br i1 %cmp11, label %if.then13, label %if.end26 - -if.then13: ; preds = %if.end - br i1 %cmp11, label %for.inc, label %for.cond35 - -if.end26: ; preds = %for.cond35, %if.end - %p.1 = phi i8 [ %p.4, %for.cond35 ], [ %k.0, %if.end ] - %k.1 = phi i8 [ %k.4, %for.cond35 ], [ 0, %if.end ] - %tobool30 = icmp ne i8 %p.0, 0 - %spec.select1 = select i1 %tobool30, i8 %k.1, i8 0 - br label %for.inc - -for.inc: ; preds = %if.end26, %if.then13 - %p.2 = phi i8 [ poison, %if.then13 ], [ %p.1, %if.end26 ] - %k.2 = phi i8 [ 0, %if.then13 ], [ %spec.select1, %if.end26 ] - %0 = load i32, ptr null, align 4 - br label %for.cond - -for.cond35: ; preds = %if.then13, %for.cond - %p.4 = phi i8 [ %k.0, %if.then13 ], [ 0, %for.cond ] - %k.4 = phi i8 [ 0, %if.then13 ], [ %k.0, %for.cond ] - %tobool36 = icmp eq i32 0, 0 - br label %if.end26 -} Index: llvm/test/CodeGen/X86/pr38795-verifier-error-pr38788.mir =================================================================== --- llvm/test/CodeGen/X86/pr38795-verifier-error-pr38788.mir +++ llvm/test/CodeGen/X86/pr38795-verifier-error-pr38788.mir @@ -167,3 +167,77 @@ JMP_1 %bb.6 ... + +# Still failed after patch for first 2 failures + +--- +name: pr38795_verifier_error_reduced_3 +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: pr38795_verifier_error_reduced_3 + ; CHECK: bb.0: + ; CHECK-NEXT: successors: %bb.5(0x40000000), %bb.1(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[DEF:%[0-9]+]]:gr32 = IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:gr32 = IMPLICIT_DEF + ; CHECK-NEXT: JCC_1 %bb.5, 4, implicit killed undef $eflags + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1: + ; CHECK-NEXT: successors: %bb.4(0x40000000), %bb.5(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[DEF2:%[0-9]+]]:gr32 = IMPLICIT_DEF + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY [[DEF]] + ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags + ; CHECK-NEXT: JCC_1 %bb.4, 5, implicit killed undef $eflags + ; CHECK-NEXT: JMP_1 %bb.5 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2: + ; CHECK-NEXT: successors: %bb.4(0x40000000), %bb.3(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: TEST32rr undef [[COPY]], [[COPY]], implicit-def $eflags + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:gr32 = IMPLICIT_DEF + ; CHECK-NEXT: JCC_1 %bb.4, 4, implicit killed undef $eflags + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3: + ; CHECK-NEXT: successors: %bb.4(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY [[MOV32r0_]] + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.4: + ; CHECK-NEXT: successors: %bb.1(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[COPY1]] + ; CHECK-NEXT: JMP_1 %bb.1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.5: + ; CHECK-NEXT: successors: %bb.2(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: JMP_1 %bb.2 + bb.0: + %0:gr32 = IMPLICIT_DEF + %1:gr32 = IMPLICIT_DEF + JCC_1 %bb.5, 4, implicit killed undef $eflags + + bb.1: + %2:gr32 = IMPLICIT_DEF + %1:gr32 = COPY killed %0 + %0:gr32 = MOV32r0 implicit-def dead $eflags + JCC_1 %bb.4, 5, implicit killed undef $eflags + JMP_1 %bb.5 + + bb.2: + TEST32rr undef %1, %1, implicit-def $eflags + %2:gr32 = IMPLICIT_DEF + JCC_1 %bb.4, 4, implicit killed undef $eflags + + bb.3: + %2:gr32 = COPY killed %0 + + bb.4: + %0:gr32 = COPY killed %2 + JMP_1 %bb.1 + + bb.5: + JMP_1 %bb.2 + +... Index: llvm/test/CodeGen/X86/pr38795.ll =================================================================== --- llvm/test/CodeGen/X86/pr38795.ll +++ llvm/test/CodeGen/X86/pr38795.ll @@ -24,21 +24,19 @@ ; CHECK-NEXT: .cfi_offset %ebx, -12 ; CHECK-NEXT: .cfi_offset %ebp, -8 ; CHECK-NEXT: xorl %ebx, %ebx -; CHECK-NEXT: # implicit-def: $ecx +; CHECK-NEXT: # implicit-def: $esi ; CHECK-NEXT: # implicit-def: $edi -; CHECK-NEXT: # implicit-def: $al -; CHECK-NEXT: # kill: killed $al +; CHECK-NEXT: # implicit-def: $ch ; CHECK-NEXT: # implicit-def: $dl ; CHECK-NEXT: # implicit-def: $ebp ; CHECK-NEXT: jmp .LBB0_1 ; CHECK-NEXT: .p2align 4, 0x90 -; CHECK-NEXT: .LBB0_16: # %for.inc -; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: movb %dl, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill -; CHECK-NEXT: movb %dh, %dl +; CHECK-NEXT: .LBB0_14: # in Loop: Header=BB0_1 Depth=1 +; CHECK-NEXT: movb %dl, %ch +; CHECK-NEXT: movl %ecx, %edx ; CHECK-NEXT: .LBB0_1: # %for.cond ; CHECK-NEXT: # =>This Loop Header: Depth=1 -; CHECK-NEXT: # Child Loop BB0_20 Depth 2 +; CHECK-NEXT: # Child Loop BB0_22 Depth 2 ; CHECK-NEXT: cmpb $8, %dl ; CHECK-NEXT: movb %dl, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill ; CHECK-NEXT: ja .LBB0_3 @@ -48,11 +46,12 @@ ; CHECK-NEXT: je .LBB0_3 ; CHECK-NEXT: # %bb.4: # %if.end ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: movl %ecx, %eax +; CHECK-NEXT: movl %esi, %ecx +; CHECK-NEXT: movl %esi, %eax ; CHECK-NEXT: cltd ; CHECK-NEXT: idivl a ; CHECK-NEXT: movzbl {{[-0-9]+}}(%e{{[sb]}}p), %edx # 1-byte Folded Reload -; CHECK-NEXT: movb %cl, %dh +; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: movl $0, h ; CHECK-NEXT: cmpb $8, %dl ; CHECK-NEXT: jg .LBB0_8 @@ -60,22 +59,22 @@ ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: movl %eax, %esi ; CHECK-NEXT: movl $.str, (%esp) -; CHECK-NEXT: movb %dh, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill +; CHECK-NEXT: movb %cl, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill ; CHECK-NEXT: calll printf -; CHECK-NEXT: movb {{[-0-9]+}}(%e{{[sb]}}p), %dh # 1-byte Reload +; CHECK-NEXT: movzbl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 1-byte Folded Reload ; CHECK-NEXT: testb %bl, %bl -; CHECK-NEXT: movl %esi, %ecx ; CHECK-NEXT: # implicit-def: $eax -; CHECK-NEXT: movb {{[-0-9]+}}(%e{{[sb]}}p), %dl # 1-byte Reload -; CHECK-NEXT: movb %dl, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill -; CHECK-NEXT: movb %dh, %dl -; CHECK-NEXT: jne .LBB0_16 -; CHECK-NEXT: jmp .LBB0_6 +; CHECK-NEXT: movb {{[-0-9]+}}(%e{{[sb]}}p), %ch # 1-byte Reload +; CHECK-NEXT: movl %ecx, %edx +; CHECK-NEXT: je .LBB0_6 +; CHECK-NEXT: jmp .LBB0_18 ; CHECK-NEXT: .p2align 4, 0x90 ; CHECK-NEXT: .LBB0_3: # %if.then ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: movl $.str, (%esp) +; CHECK-NEXT: movb %ch, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill ; CHECK-NEXT: calll printf +; CHECK-NEXT: movb {{[-0-9]+}}(%e{{[sb]}}p), %ch # 1-byte Reload ; CHECK-NEXT: movzbl {{[-0-9]+}}(%e{{[sb]}}p), %edx # 1-byte Folded Reload ; CHECK-NEXT: # implicit-def: $eax ; CHECK-NEXT: .LBB0_6: # %for.cond35 @@ -86,74 +85,80 @@ ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: testb %bl, %bl ; CHECK-NEXT: jne .LBB0_12 -; CHECK-NEXT: .LBB0_17: # %if.end39 +; CHECK-NEXT: .LBB0_19: # %if.end39 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: testl %eax, %eax -; CHECK-NEXT: je .LBB0_19 -; CHECK-NEXT: # %bb.18: # %if.then41 +; CHECK-NEXT: je .LBB0_21 +; CHECK-NEXT: # %bb.20: # %if.then41 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: movl $0, {{[0-9]+}}(%esp) ; CHECK-NEXT: movl $fn, {{[0-9]+}}(%esp) ; CHECK-NEXT: movl $.str, (%esp) ; CHECK-NEXT: calll printf -; CHECK-NEXT: .LBB0_19: # %for.end46 +; CHECK-NEXT: .LBB0_21: # %for.end46 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: # implicit-def: $dl -; CHECK-NEXT: # implicit-def: $dh +; CHECK-NEXT: # implicit-def: $ch +; CHECK-NEXT: # implicit-def: $cl ; CHECK-NEXT: # implicit-def: $ebp -; CHECK-NEXT: jmp .LBB0_20 +; CHECK-NEXT: jmp .LBB0_22 ; CHECK-NEXT: .p2align 4, 0x90 ; CHECK-NEXT: .LBB0_8: # %if.end21 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: # implicit-def: $ebp -; CHECK-NEXT: jmp .LBB0_9 +; CHECK-NEXT: testb %bl, %bl +; CHECK-NEXT: je .LBB0_13 ; CHECK-NEXT: .p2align 4, 0x90 +; CHECK-NEXT: .LBB0_10: # in Loop: Header=BB0_1 Depth=1 +; CHECK-NEXT: # implicit-def: $eax +; CHECK-NEXT: testb %bl, %bl +; CHECK-NEXT: je .LBB0_19 +; CHECK-NEXT: .LBB0_12: # in Loop: Header=BB0_1 Depth=1 +; CHECK-NEXT: # implicit-def: $edi +; CHECK-NEXT: # implicit-def: $ch +; CHECK-NEXT: # implicit-def: $dl +; CHECK-NEXT: # implicit-def: $ebp +; CHECK-NEXT: testl %edi, %edi +; CHECK-NEXT: jne .LBB0_11 ; CHECK-NEXT: .LBB0_7: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: xorl %edi, %edi -; CHECK-NEXT: movb %dl, %dh -; CHECK-NEXT: movb {{[-0-9]+}}(%e{{[sb]}}p), %dl # 1-byte Reload +; CHECK-NEXT: movb %dl, %cl ; CHECK-NEXT: .p2align 4, 0x90 -; CHECK-NEXT: .LBB0_20: # %for.cond47 +; CHECK-NEXT: .LBB0_22: # %for.cond47 ; CHECK-NEXT: # Parent Loop BB0_1 Depth=1 ; CHECK-NEXT: # => This Inner Loop Header: Depth=2 ; CHECK-NEXT: testb %bl, %bl -; CHECK-NEXT: jne .LBB0_20 -; CHECK-NEXT: # %bb.21: # %for.cond47 -; CHECK-NEXT: # in Loop: Header=BB0_20 Depth=2 +; CHECK-NEXT: jne .LBB0_22 +; CHECK-NEXT: # %bb.23: # %for.cond47 +; CHECK-NEXT: # in Loop: Header=BB0_22 Depth=2 ; CHECK-NEXT: testb %bl, %bl -; CHECK-NEXT: jne .LBB0_20 -; CHECK-NEXT: .LBB0_9: # %ae -; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 +; CHECK-NEXT: jne .LBB0_22 +; CHECK-NEXT: # %bb.24: # in Loop: Header=BB0_1 Depth=1 +; CHECK-NEXT: movb %ch, %dl ; CHECK-NEXT: testb %bl, %bl ; CHECK-NEXT: jne .LBB0_10 -; CHECK-NEXT: # %bb.13: # %if.end26 +; CHECK-NEXT: .LBB0_13: # %if.end26 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: xorl %ecx, %ecx +; CHECK-NEXT: xorl %esi, %esi ; CHECK-NEXT: testb %dl, %dl -; CHECK-NEXT: je .LBB0_16 -; CHECK-NEXT: # %bb.14: # %if.end26 +; CHECK-NEXT: je .LBB0_14 +; CHECK-NEXT: # %bb.15: # %if.end26 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: testl %ebp, %ebp ; CHECK-NEXT: jne .LBB0_16 -; CHECK-NEXT: # %bb.15: # %if.then31 +; CHECK-NEXT: # %bb.17: # %if.then31 ; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: xorl %ecx, %ecx +; CHECK-NEXT: xorl %esi, %esi +; CHECK-NEXT: movb %dl, %ch ; CHECK-NEXT: xorl %ebp, %ebp -; CHECK-NEXT: jmp .LBB0_16 +; CHECK-NEXT: .LBB0_18: # %for.inc +; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1 +; CHECK-NEXT: movl %ecx, %edx +; CHECK-NEXT: jmp .LBB0_1 ; CHECK-NEXT: .p2align 4, 0x90 -; CHECK-NEXT: .LBB0_10: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: # implicit-def: $eax -; CHECK-NEXT: testb %bl, %bl -; CHECK-NEXT: je .LBB0_17 -; CHECK-NEXT: .LBB0_12: # in Loop: Header=BB0_1 Depth=1 -; CHECK-NEXT: # implicit-def: $edi -; CHECK-NEXT: # implicit-def: $cl -; CHECK-NEXT: # kill: killed $cl -; CHECK-NEXT: # implicit-def: $dl -; CHECK-NEXT: # implicit-def: $ebp -; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: jne .LBB0_11 -; CHECK-NEXT: jmp .LBB0_7 +; CHECK-NEXT: .LBB0_16: # in Loop: Header=BB0_1 Depth=1 +; CHECK-NEXT: movb %dl, %ch +; CHECK-NEXT: movl %ecx, %edx +; CHECK-NEXT: jmp .LBB0_1 entry: br label %for.cond @@ -259,3 +264,91 @@ } declare dso_local void @printf(ptr nocapture readonly, ...) local_unnamed_addr + + +; Testcase used to fail -verify-coalescing, reduced IR test which +; failed. +define void @verifier_error_reduced_issue38788(i1 %cmp11) { +; CHECK-LABEL: verifier_error_reduced_issue38788: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushl %ebx +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: .cfi_offset %ebx, -8 +; CHECK-NEXT: movzbl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: xorl %ecx, %ecx +; CHECK-NEXT: xorl %ebx, %ebx +; CHECK-NEXT: jmp .LBB1_1 +; CHECK-NEXT: .p2align 4, 0x90 +; CHECK-NEXT: .LBB1_7: # %if.end26 +; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: movl %ecx, %edx +; CHECK-NEXT: .LBB1_8: # %for.inc +; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: movl %eax, %ecx +; CHECK-NEXT: movl %edx, %ebx +; CHECK-NEXT: movzbl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: .LBB1_1: # %for.cond +; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: testb $1, %al +; CHECK-NEXT: je .LBB1_3 +; CHECK-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: jmp .LBB1_5 +; CHECK-NEXT: .p2align 4, 0x90 +; CHECK-NEXT: .LBB1_3: # %if.end +; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: testb $1, %al +; CHECK-NEXT: je .LBB1_4 +; CHECK-NEXT: # %bb.9: # %if.then13 +; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: testb $1, %al +; CHECK-NEXT: movl %ebx, %eax +; CHECK-NEXT: movl $0, %ebx +; CHECK-NEXT: jne .LBB1_8 +; CHECK-NEXT: jmp .LBB1_5 +; CHECK-NEXT: .p2align 4, 0x90 +; CHECK-NEXT: .LBB1_4: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: movl %ebx, %eax +; CHECK-NEXT: xorl %ebx, %ebx +; CHECK-NEXT: .LBB1_5: # %if.end26 +; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: testb %cl, %cl +; CHECK-NEXT: je .LBB1_7 +; CHECK-NEXT: # %bb.6: # %if.end26 +; CHECK-NEXT: # in Loop: Header=BB1_1 Depth=1 +; CHECK-NEXT: movl %ebx, %ecx +; CHECK-NEXT: jmp .LBB1_7 +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %p.0 = phi i8 [ 0, %entry ], [ %p.2, %for.inc ] + %k.0 = phi i8 [ 0, %entry ], [ %k.2, %for.inc ] + br i1 %cmp11, label %for.cond35, label %if.end + +if.end: ; preds = %for.cond + br i1 %cmp11, label %if.then13, label %if.end26 + +if.then13: ; preds = %if.end + br i1 %cmp11, label %for.inc, label %for.cond35 + +if.end26: ; preds = %for.cond35, %if.end + %p.1 = phi i8 [ %p.4, %for.cond35 ], [ %k.0, %if.end ] + %k.1 = phi i8 [ %k.4, %for.cond35 ], [ 0, %if.end ] + %tobool30 = icmp ne i8 %p.0, 0 + %spec.select1 = select i1 %tobool30, i8 %k.1, i8 0 + br label %for.inc + +for.inc: ; preds = %if.end26, %if.then13 + %p.2 = phi i8 [ poison, %if.then13 ], [ %p.1, %if.end26 ] + %k.2 = phi i8 [ 0, %if.then13 ], [ %spec.select1, %if.end26 ] + %0 = load i32, ptr null, align 4 + br label %for.cond + +for.cond35: ; preds = %if.then13, %for.cond + %p.4 = phi i8 [ %k.0, %if.then13 ], [ 0, %for.cond ] + %k.4 = phi i8 [ 0, %if.then13 ], [ %k.0, %for.cond ] + %tobool36 = icmp eq i32 0, 0 + br label %if.end26 +}