[llvm] r312620 - [x86] Fix PR34377 by disabling cmov conversion when we relied on it

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 5 23:28:08 PDT 2017


Author: chandlerc
Date: Tue Sep  5 23:28:08 2017
New Revision: 312620

URL: http://llvm.org/viewvc/llvm-project?rev=312620&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/X86/X86CmovConversion.cpp
    llvm/trunk/test/CodeGen/X86/cmov-into-branch.ll

Modified: llvm/trunk/lib/Target/X86/X86CmovConversion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CmovConversion.cpp?rev=312620&r1=312619&r2=312620&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86CmovConversion.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86CmovConversion.cpp Tue Sep  5 23:28:08 2017
@@ -289,6 +289,16 @@ bool X86CmovConverterPass::collectCmovCa
             // 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.

Modified: llvm/trunk/test/CodeGen/X86/cmov-into-branch.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cmov-into-branch.ll?rev=312620&r1=312619&r2=312620&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/cmov-into-branch.ll (original)
+++ llvm/trunk/test/CodeGen/X86/cmov-into-branch.ll Tue Sep  5 23:28:08 2017
@@ -61,6 +61,24 @@ define i32 @test5(i32 %a, i32* nocapture
   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
 ; 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
 ; 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




More information about the llvm-commits mailing list