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

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 19 16:35:50 PDT 2017


Author: chandlerc
Date: Sat Aug 19 16:35:50 2017
New Revision: 311267

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

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

Modified: llvm/trunk/lib/Target/X86/X86CmovConversion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CmovConversion.cpp?rev=311267&r1=311266&r2=311267&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86CmovConversion.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86CmovConversion.cpp Sat Aug 19 16:35:50 2017
@@ -646,9 +646,17 @@ void X86CmovConverterPass::convertCmovIn
     // 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;
     }
 

Modified: llvm/trunk/test/CodeGen/X86/x86-cmov-converter.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/x86-cmov-converter.ll?rev=311267&r1=311266&r2=311267&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/x86-cmov-converter.ll (original)
+++ llvm/trunk/test/CodeGen/X86/x86-cmov-converter.ll Sat Aug 19 16:35:50 2017
@@ -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"}




More information about the llvm-commits mailing list