mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
[x86] Fix PR34377 by disabling cmov conversion when we relied on it
performing a zext of a register. On the PR there is discussion of how to more effectively handle this, but this patch prevents us from miscompiling code. Differential Revision: https://reviews.llvm.org/D37504 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312620 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
922eae4d2e
commit
1467a089bc
@ -289,6 +289,16 @@ bool X86CmovConverterPass::collectCmovCandidates(
|
||||
// Can't handle mixed conditions with memory operands.
|
||||
SkipGroup = true;
|
||||
}
|
||||
// Check if we were relying on zero-extending behavior of the CMOV.
|
||||
if (!SkipGroup &&
|
||||
llvm::any_of(
|
||||
MRI->use_nodbg_instructions(I.defs().begin()->getReg()),
|
||||
[&](MachineInstr &UseI) {
|
||||
return UseI.getOpcode() == X86::SUBREG_TO_REG;
|
||||
}))
|
||||
// FIXME: We should model the cost of using an explicit MOV to handle
|
||||
// the zero-extension rather than just refusing to handle this.
|
||||
SkipGroup = true;
|
||||
continue;
|
||||
}
|
||||
// If Group is empty, keep looking for first CMOV in the range.
|
||||
|
@ -61,6 +61,24 @@ define i32 @test5(i32 %a, i32* nocapture %b, i32 %x, i32 %y) {
|
||||
ret i32 %cond5
|
||||
}
|
||||
|
||||
; Zero-extended select.
|
||||
define void @test6(i32 %a, i32 %x, i32* %y.ptr, i64* %z.ptr) {
|
||||
; CHECK-LABEL: test6:
|
||||
; CHECK: # BB#0: # %entry
|
||||
; CHECK-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def>
|
||||
; CHECK-NEXT: testl %edi, %edi
|
||||
; CHECK-NEXT: cmovnsl (%rdx), %esi
|
||||
; CHECK-NEXT: movq %rsi, (%rcx)
|
||||
; CHECK-NEXT: retq
|
||||
entry:
|
||||
%y = load i32, i32* %y.ptr
|
||||
%cmp = icmp slt i32 %a, 0
|
||||
%z = select i1 %cmp, i32 %x, i32 %y
|
||||
%z.ext = zext i32 %z to i64
|
||||
store i64 %z.ext, i64* %z.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
; If a select is not obviously predictable, don't turn it into a branch.
|
||||
define i32 @weighted_select1(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: weighted_select1:
|
||||
@ -79,10 +97,10 @@ define i32 @weighted_select2(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: weighted_select2:
|
||||
; CHECK: # BB#0:
|
||||
; CHECK-NEXT: testl %edi, %edi
|
||||
; CHECK-NEXT: jne .LBB5_2
|
||||
; CHECK-NEXT: jne .LBB6_2
|
||||
; CHECK-NEXT: # BB#1: # %select.false
|
||||
; CHECK-NEXT: movl %esi, %edi
|
||||
; CHECK-NEXT: .LBB5_2: # %select.end
|
||||
; CHECK-NEXT: .LBB6_2: # %select.end
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%cmp = icmp ne i32 %a, 0
|
||||
@ -98,11 +116,11 @@ define i32 @weighted_select3(i32 %a, i32 %b) {
|
||||
; CHECK-LABEL: weighted_select3:
|
||||
; CHECK: # BB#0:
|
||||
; CHECK-NEXT: testl %edi, %edi
|
||||
; CHECK-NEXT: je .LBB6_1
|
||||
; CHECK-NEXT: je .LBB7_1
|
||||
; CHECK-NEXT: # BB#2: # %select.end
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
; CHECK-NEXT: .LBB6_1: # %select.false
|
||||
; CHECK-NEXT: .LBB7_1: # %select.false
|
||||
; CHECK-NEXT: movl %esi, %edi
|
||||
; CHECK-NEXT: movl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
|
Loading…
Reference in New Issue
Block a user