diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2017-09-06 06:28:08 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2017-09-06 06:28:08 +0000 |
commit | 585bfc844318870ebdb10ff99e4edc20013fe3da (patch) | |
tree | 524b13392f284f37703ff6610a1224db1a20277f | |
parent | 5ebe94a84d6aba9e5c449a2c7913d3735dd7ea29 (diff) | |
download | bcm5719-llvm-585bfc844318870ebdb10ff99e4edc20013fe3da.tar.gz bcm5719-llvm-585bfc844318870ebdb10ff99e4edc20013fe3da.zip |
[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
llvm-svn: 312620
-rw-r--r-- | llvm/lib/Target/X86/X86CmovConversion.cpp | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/cmov-into-branch.ll | 26 |
2 files changed, 32 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/X86CmovConversion.cpp b/llvm/lib/Target/X86/X86CmovConversion.cpp index f7967004e20..e31a7949f0b 100644 --- a/llvm/lib/Target/X86/X86CmovConversion.cpp +++ b/llvm/lib/Target/X86/X86CmovConversion.cpp @@ -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. diff --git a/llvm/test/CodeGen/X86/cmov-into-branch.ll b/llvm/test/CodeGen/X86/cmov-into-branch.ll index e3803950164..0a2246700e6 100644 --- a/llvm/test/CodeGen/X86/cmov-into-branch.ll +++ b/llvm/test/CodeGen/X86/cmov-into-branch.ll @@ -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 |