llvm.org GIT mirror llvm / 6c31f1e
[x86] Fix EFLAGS copy lowering to correctly handle walking past uses in multiple successors where some of the uses end up killing the EFLAGS register. There was a bug where rather than skipping to the next basic block queued up with uses once we saw a kill, we stopped processing the blocks entirely. =/ Test case produces completely nonsensical code w/o this tiny fix. This was found testing Speculative Load Hardening and split out of that work. Differential Revision: https://reviews.llvm.org/D49211 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336874 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 1 year, 8 months ago
2 changed file(s) with 80 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
554554
555555 // If the flags were killed, we're done with this block.
556556 if (FlagsKilled)
557 break;
557 continue;
558558
559559 // Otherwise we need to scan successors for ones where the flags live-in
560560 // and queue those up for processing.
7070 entry:
7171 call void @foo()
7272 ret void
73 }
74
75 define i64 @test_branch_with_livein_and_kill(i64 %a, i64 %b) {
76 entry:
77 call void @foo()
78 ret i64 0
7379 }
7480 ...
7581 ---
552558 RET 0
553559
554560 ...
561 ---
562 name: test_branch_with_livein_and_kill
563 # CHECK-LABEL: name: test_branch_with_livein_and_kill
564 liveins:
565 - { reg: '$rdi', virtual-reg: '%0' }
566 - { reg: '$rsi', virtual-reg: '%1' }
567 body: |
568 bb.0:
569 successors: %bb.1, %bb.2, %bb.3
570 liveins: $rdi, $rsi
571
572 %0:gr64 = COPY $rdi
573 %1:gr64 = COPY $rsi
574 CMP64rr %0, %1, implicit-def $eflags
575 %2:gr64 = COPY $eflags
576 ; CHECK-NOT: COPY{{( killed)?}} $eflags
577 ; CHECK: %[[S_REG:[^:]*]]:gr8 = SETSr implicit $eflags
578 ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETNEr implicit $eflags
579 ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
580 ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
581 ; CHECK-NOT: COPY{{( killed)?}} $eflags
582
583 ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
584 CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
585 ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
586
587 $eflags = COPY %2
588 JA_1 %bb.1, implicit $eflags
589 JB_1 %bb.2, implicit $eflags
590 JMP_1 %bb.3
591 ; CHECK-NOT: $eflags =
592 ;
593 ; CHECK: TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
594 ; CHECK-NEXT: JNE_1 %bb.1, implicit killed $eflags
595 ; CHECK-SAME: {{$[[:space:]]}}
596 ; CHECK-NEXT: bb.4:
597 ; CHECK-NEXT: successors: {{.*$}}
598 ; CHECK-SAME: {{$[[:space:]]}}
599 ; CHECK-NEXT: TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
600 ; CHECK-NEXT: JNE_1 %bb.2, implicit killed $eflags
601 ; CHECK-NEXT: JMP_1 %bb.3
602
603 bb.1:
604 liveins: $eflags
605
606 %3:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
607 ; CHECK-NOT: $eflags =
608 ; CHECK: TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
609 ; CHECK-NEXT: %3:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
610 $rax = COPY %3
611 RET 0, $rax
612
613 bb.2:
614 liveins: $eflags
615
616 %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
617 ; CHECK-NOT: $eflags =
618 ; CHECK: TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
619 ; CHECK-NEXT: %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
620 $rax = COPY %4
621 RET 0, $rax
622
623 bb.3:
624 liveins: $eflags
625
626 %5:gr64 = CMOVS64rr %0, %1, implicit killed $eflags
627 ; CHECK-NOT: $eflags =
628 ; CHECK: TEST8rr %[[S_REG]], %[[S_REG]], implicit-def $eflags
629 ; CHECK-NEXT: %5:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
630 $rax = COPY %5
631 RET 0, $rax
632
633 ...