reapply my fix for PR8961 with a tweak to properly handle
authorChris Lattner <sabre@nondot.org>
Sun, 16 Jan 2011 02:27:38 +0000 (02:27 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 16 Jan 2011 02:27:38 +0000 (02:27 +0000)
multi-instruction sequences like calls.  Many thanks to Jakob for
finding a testcase.

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

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Target/X86/X86FastISel.cpp
test/CodeGen/X86/fast-isel-gep.ll

index f5f267cb070ebc6bf677821f401e26416dacf449..ae63f2e657f4188ba43a678212d2f52c83d4f57e 100644 (file)
@@ -771,8 +771,16 @@ bool SelectionDAGISel::TryToFoldFastISelLoad(const LoadInst *LI,
   assert(RI.getOperand().isUse() &&
          "The only use of the vreg must be a use, we haven't emitted the def!");
 
+  MachineInstr *User = &*RI;
+  
+  // Set the insertion point properly.  Folding the load can cause generation of
+  // other random instructions (like sign extends) for addressing modes, make
+  // sure they get inserted in a logical place before the new instruction.
+  FuncInfo->InsertPt = User;
+  FuncInfo->MBB = User->getParent();
+
   // Ask the target to try folding the load.
-  return FastIS->TryToFoldLoad(&*RI, RI.getOperandNo(), LI);
+  return FastIS->TryToFoldLoad(User, RI.getOperandNo(), LI);
 }
 
 #ifndef NDEBUG
@@ -890,11 +898,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
           if (Inst != Begin)
             BeforeInst = llvm::prior(llvm::prior(BI));
           if (BeforeInst && isa<LoadInst>(BeforeInst) &&
-              BeforeInst->hasOneUse() && *BeforeInst->use_begin() == Inst) {
-            FastIS->recomputeInsertPt();
-            if (TryToFoldFastISelLoad(cast<LoadInst>(BeforeInst), FastIS))
-              --BI; // If we succeeded, don't re-select the load.
-          }
+              BeforeInst->hasOneUse() && *BeforeInst->use_begin() == Inst &&
+              TryToFoldFastISelLoad(cast<LoadInst>(BeforeInst), FastIS))
+            --BI; // If we succeeded, don't re-select the load.
           continue;
         }
 
index f29d127c85d1c4b086a183d49ed979bd55b9c196..9d42ac2e470c2ccf63be6b44fba931918446c8d1 100644 (file)
@@ -1933,7 +1933,7 @@ bool X86FastISel::TryToFoldLoad(MachineInstr *MI, unsigned OpNo,
     XII.foldMemoryOperandImpl(*FuncInfo.MF, MI, OpNo, AddrOps, Size, Alignment);
   if (Result == 0) return false;
 
-  MI->getParent()->insert(MI, Result);
+  FuncInfo.MBB->insert(FuncInfo.InsertPt, Result);
   MI->eraseFromParent();
   return true;
 }
index 577dd7223a4d7a9464f805c5d44d337bb2b6e5ad..622a1ff831d03a703bd1d48e33e0c895c791c246 100644 (file)
@@ -70,3 +70,20 @@ entry:
 ; X64: test4:
 ; X64: 128(%r{{.*}},%r{{.*}},8)
 }
+
+; PR8961 - Make sure the sext for the GEP addressing comes before the load that
+; is folded.
+define i64 @test5(i8* %A, i32 %I, i64 %B) nounwind {
+  %v8 = getelementptr i8* %A, i32 %I
+  %v9 = bitcast i8* %v8 to i64*
+  %v10 = load i64* %v9
+  %v11 = add i64 %B, %v10
+  ret i64 %v11
+; X64: test5:
+; X64: movslq  %esi, %rax
+; X64-NEXT: movq       (%rdi,%rax), %rax
+; X64-NEXT: addq       %rdx, %rax
+; X64-NEXT: ret
+}
+
+