SCEVExpander's InsertCastOfTo knows how to move existing cast
authorDan Gohman <gohman@apple.com>
Wed, 22 Apr 2009 16:11:16 +0000 (16:11 +0000)
committerDan Gohman <gohman@apple.com>
Wed, 22 Apr 2009 16:11:16 +0000 (16:11 +0000)
instructions in order to avoid inserting new ones. However, if
the cast instruction is the SCEVExpander's InsertPt, this
causes subsequently emitted instructions to be inserted near
the cast, and not at the location of the original insert point.
Fix this by adjusting the insert point in such cases.
This fixes PR4009.

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

lib/Analysis/ScalarEvolutionExpander.cpp
test/Transforms/IndVarSimplify/casted-argument.ll [new file with mode: 0644]

index 394ad6c01097ca1f439c7409ffc17ecbe28db7b0..74c11183e81e15e0729a780af032b30bdbccd955 100644 (file)
@@ -49,6 +49,9 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
             // If the cast isn't the first instruction of the function, move it.
             if (BasicBlock::iterator(CI) != 
                 A->getParent()->getEntryBlock().begin()) {
+              // If the CastInst is the insert point, change the insert point.
+              if (CI == InsertPt) ++InsertPt;
+              // Splice the cast at the beginning of the entry block.
               CI->moveBefore(A->getParent()->getEntryBlock().begin());
             }
             return CI;
@@ -71,6 +74,8 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
             It = cast<InvokeInst>(I)->getNormalDest()->begin();
           while (isa<PHINode>(It)) ++It;
           if (It != BasicBlock::iterator(CI)) {
+            // If the CastInst is the insert point, change the insert point.
+            if (CI == InsertPt) ++InsertPt;
             // Splice the cast immediately after the operand in question.
             CI->moveBefore(It);
           }
diff --git a/test/Transforms/IndVarSimplify/casted-argument.ll b/test/Transforms/IndVarSimplify/casted-argument.ll
new file mode 100644 (file)
index 0000000..ae41e3a
--- /dev/null
@@ -0,0 +1,24 @@
+; RUN: llvm-as < %s | opt -indvars -disable-output
+; PR4009
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i386-pc-linux-gnu"
+
+define void @safe_bcopy(i8* %to) nounwind {
+entry:
+       %cmp11 = icmp ult i8* %to, null         ; <i1> [#uses=1]
+       br i1 %cmp11, label %loop, label %return
+
+return:                ; preds = %entry
+       ret void
+
+loop:          ; preds = %loop, %if.else
+       %pn = phi i8* [ %ge, %loop ], [ null, %entry ]          ; <i8*> [#uses=1]
+       %cp = ptrtoint i8* %to to i32           ; <i32> [#uses=1]
+       %su = sub i32 0, %cp            ; <i32> [#uses=1]
+       %ge = getelementptr i8* %pn, i32 %su            ; <i8*> [#uses=2]
+       tail call void @bcopy(i8* %ge) nounwind
+       br label %loop
+}
+
+declare void @bcopy(i8* nocapture) nounwind