1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[x86] Fix an even stranger corner case where we have multiple levels of

cmov self-refrencing.

Pointed out by Amjad Aboud in code review, test case minorly simplified
from the one he posted.

llvm-svn: 311267
This commit is contained in:
Chandler Carruth 2017-08-19 23:35:50 +00:00
parent 99196f8bed
commit d13552d52b
2 changed files with 32 additions and 2 deletions

View File

@ -646,9 +646,17 @@ void X86CmovConverterPass::convertCmovInstsToBranches(
// Skip any CMOVs in this group which don't load from memory.
if (!MI.mayLoad()) {
// Remember the false-side register input.
FalseBBRegRewriteTable[MI.getOperand(0).getReg()] =
unsigned FalseReg =
MI.getOperand(X86::getCondFromCMovOpc(MI.getOpcode()) == CC ? 1 : 2)
.getReg();
// Walk back through any intermediate cmovs referenced.
for (;;) {
auto FRIt = FalseBBRegRewriteTable.find(FalseReg);
if (FRIt == FalseBBRegRewriteTable.end())
break;
FalseReg = FRIt->second;
}
FalseBBRegRewriteTable[MI.getOperand(0).getReg()] = FalseReg;
continue;
}

View File

@ -428,7 +428,8 @@ entry:
}
; Test that we can convert a group of cmovs where only one has a memory
; operand and where that memory operand's registers come from a prior cmov in the group.
; operand and where that memory operand's registers come from a prior cmov in
; the group.
define i32 @test_cmov_memoperand_in_group_reuse_for_addr(i32 %a, i32 %b, i32* %x, i32* %y) #0 {
; CHECK-LABEL: test_cmov_memoperand_in_group_reuse_for_addr:
entry:
@ -467,4 +468,25 @@ entry:
ret i32 %z
}
; Test that we can convert a group of cmovs where only one has a memory
; operand and where that memory operand's registers come from a prior cmov and
; where that cmov gets *its* input from a prior cmov in the group.
define i32 @test_cmov_memoperand_in_group_reuse_for_addr3(i32 %a, i32 %b, i32* %x, i32* %y, i32* %z) #0 {
; CHECK-LABEL: test_cmov_memoperand_in_group_reuse_for_addr3:
entry:
%cond = icmp ugt i32 %a, %b
; CHECK: cmpl
%p = select i1 %cond, i32* %x, i32* %y
%p2 = select i1 %cond, i32* %z, i32* %p
%load = load i32, i32* %p2
%r = select i1 %cond, i32 %a, i32 %load
; CHECK-NOT: cmov
; CHECK: ja [[FALSE_BB:.*]]
; CHECK: movl (%r{{..}}), %[[R:.*]]
; CHECK: [[FALSE_BB]]:
; CHECK: movl %[[R]], %eax
; CHECK: retq
ret i32 %r
}
attributes #0 = {"target-cpu"="x86-64"}