<p dir="ltr">Lot of cutting and pasting here. Any chance of a refactor?</p>
<div class="gmail_quote">On Jun 25, 2014 1:45 PM, "Juergen Ributzka" <<a href="mailto:juergen@apple.com">juergen@apple.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: ributzka<br>
Date: Wed Jun 25 15:06:12 2014<br>
New Revision: 211730<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=211730&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=211730&view=rev</a><br>
Log:<br>
[FastISel][X86] Only fold the cmp into the select when both instructions are in the same basic block.<br>
<br>
If the cmp is in a different basic block, then it is possible that not all<br>
operands of that compare have defined registers. This can happen when one of<br>
the operands to the cmp is a load and the load gets folded into the cmp. In<br>
this case FastISel will skip the load instruction and the vreg is never<br>
defined.<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/X86/fast-isel-select-cmp.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/X86/X86FastISel.cpp<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=211730&r1=211729&r2=211730&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=211730&r1=211729&r2=211730&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Jun 25 15:06:12 2014<br>
@@ -1754,8 +1754,11 @@ bool X86FastISel::X86FastEmitCMoveSelect<br>
   const TargetRegisterClass *RC = TLI.getRegClassFor(RetVT);<br>
   bool NeedTest = true;<br>
<br>
-  // Optimize conditons coming from a compare.<br>
-  if (const auto *CI = dyn_cast<CmpInst>(Cond)) {<br>
+  // Optimize conditons coming from a compare if both instructions are in the<br>
+  // same basic block (values defined in other basic blocks may not have<br>
+  // initialized registers).<br>
+  const auto *CI = dyn_cast<CmpInst>(Cond);<br>
+  if (CI && (CI->getParent() == I->getParent())) {<br>
     CmpInst::Predicate Predicate = optimizeCmpPredicate(CI);<br>
<br>
     // FCMP_OEQ and FCMP_UNE cannot be checked with a single instruction.<br>
@@ -1927,8 +1930,11 @@ bool X86FastISel::X86FastEmitSSESelect(c<br>
   if (!isTypeLegal(I->getType(), RetVT))<br>
     return false;<br>
<br>
+  // Optimize conditons coming from a compare if both instructions are in the<br>
+  // same basic block (values defined in other basic blocks may not have<br>
+  // initialized registers).<br>
   const auto *CI = dyn_cast<FCmpInst>(I->getOperand(0));<br>
-  if (!CI)<br>
+  if (!CI || (CI->getParent() != I->getParent()))<br>
     return false;<br>
<br>
   if (I->getType() != CI->getOperand(0)->getType() ||<br>
@@ -2023,8 +2029,12 @@ bool X86FastISel::X86FastEmitPseudoSelec<br>
<br>
   const Value *Cond = I->getOperand(0);<br>
   X86::CondCode CC = X86::COND_NE;<br>
-  // Don't emit a test if the condition comes from a compare.<br>
-  if (const auto *CI = dyn_cast<CmpInst>(Cond)) {<br>
+<br>
+  // Optimize conditons coming from a compare if both instructions are in the<br>
+  // same basic block (values defined in other basic blocks may not have<br>
+  // initialized registers).<br>
+  const auto *CI = dyn_cast<CmpInst>(Cond);<br>
+  if (CI && (CI->getParent() == I->getParent())) {<br>
     bool NeedSwap;<br>
     std::tie(CC, NeedSwap) = getX86ConditonCode(CI->getPredicate());<br>
     if (CC > X86::LAST_VALID_COND)<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/fast-isel-select-cmp.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-select-cmp.ll?rev=211730&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-select-cmp.ll?rev=211730&view=auto</a><br>

==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/fast-isel-select-cmp.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/fast-isel-select-cmp.ll Wed Jun 25 15:06:12 2014<br>
@@ -0,0 +1,50 @@<br>
+; RUN: llc < %s -O0 -mtriple=x86_64-apple-darwin10 | FileCheck %s<br>
+<br>
+; Test if we do not fold the cmp into select if the instructions are in<br>
+; different basic blocks.<br>
+<br>
+define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {<br>
+; CHECK-LABEL: select_cmp_cmov_i32<br>
+; CHECK-LABEL: continue<br>
+; CHECK-NOT:   cmp<br>
+  %1 = icmp ult i32 %a, %b<br>
+  br i1 %1, label %continue, label %exit<br>
+<br>
+continue:<br>
+  %2 = select i1 %1, i32 %a, i32 %b<br>
+  ret i32 %2<br>
+<br>
+exit:<br>
+  ret i32 -1<br>
+}<br>
+<br>
+define float @select_fcmp_oeq_f32(float %a, float %b, float %c, float %d) {<br>
+; CHECK-LABEL: select_fcmp_oeq_f32<br>
+; CHECK-LABEL: continue<br>
+; CHECK-NOT:   cmp<br>
+  %1 = fcmp oeq float %a, %b<br>
+  br i1 %1, label %continue, label %exit<br>
+<br>
+continue:<br>
+  %2 = select i1 %1, float %c, float %d<br>
+  ret float %2<br>
+<br>
+exit:<br>
+  ret float -1.0<br>
+}<br>
+<br>
+define float @select_fcmp_one_f32(float %a, float %b, float %c, float %d) {<br>
+; CHECK-LABEL: select_fcmp_one_f32<br>
+; CHECK-LABEL: continue<br>
+; CHECK-NOT:   ucomi<br>
+  %1 = fcmp one float %a, %b<br>
+  br i1 %1, label %continue, label %exit<br>
+<br>
+continue:<br>
+  %2 = select i1 %1, float %c, float %d<br>
+  ret float %2<br>
+<br>
+exit:<br>
+  ret float -1.0<br>
+}<br>
+<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>