Fix x86 fast-isel's cmp+branch folding to avoid folding when the
authorDan Gohman <gohman@apple.com>
Sat, 21 Aug 2010 02:32:36 +0000 (02:32 +0000)
committerDan Gohman <gohman@apple.com>
Sat, 21 Aug 2010 02:32:36 +0000 (02:32 +0000)
comparison is in a different basic block from the branch. In such
cases, the comparison's operands may not have initialized virtual
registers available.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111709 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FastISel.cpp
test/CodeGen/X86/fast-isel-cmp-branch.ll [new file with mode: 0644]

index b7341f93eedd8c22e69b350463a5eb1a90de87e0..0c70eec4827fb12650a0081cc6ac904f084424d6 100644 (file)
@@ -960,9 +960,11 @@ bool X86FastISel::X86SelectBranch(const Instruction *I) {
   MachineBasicBlock *TrueMBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
   MachineBasicBlock *FalseMBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
 
-  // Fold the common case of a conditional branch with a comparison.
+  // Fold the common case of a conditional branch with a comparison
+  // in the same block (values defined on other blocks may not have
+  // initialized registers).
   if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
-    if (CI->hasOneUse()) {
+    if (CI->hasOneUse() && CI->getParent() == I->getParent()) {
       EVT VT = TLI.getValueType(CI->getOperand(0)->getType());
 
       // Try to take advantage of fallthrough opportunities.
diff --git a/test/CodeGen/X86/fast-isel-cmp-branch.ll b/test/CodeGen/X86/fast-isel-cmp-branch.ll
new file mode 100644 (file)
index 0000000..4ab1bc6
--- /dev/null
@@ -0,0 +1,29 @@
+; RUN: llc -O0 -march=x86-64 -asm-verbose=false < %s | FileCheck %s
+; rdar://8337108
+
+; Fast-isel shouldn't try to look through the compare because it's in a
+; different basic block, so its operands aren't necessarily exported
+; for cross-block usage.
+
+; CHECK: movb    %al, 7(%rsp)
+; CHECK: callq   {{_?}}bar
+; CHECK: movb    7(%rsp), %al
+
+declare void @bar()
+
+define void @foo(i32 %a, i32 %b) nounwind {
+entry:
+  %q = add i32 %a, 7
+  %r = add i32 %b, 9
+  %t = icmp ult i32 %q, %r
+  invoke void @bar() to label %next unwind label %unw
+next:
+  br i1 %t, label %true, label %return
+true:
+  call void @bar()
+  br label %return
+return:
+  ret void
+unw:
+  unreachable
+}