[llvm] r237009 - [RewriteStatepointsForGC] Fix a bug on creating gc_relocate for pointer to vector of pointers

Sanjoy Das sanjoy at playingwithpointers.com
Mon May 11 11:49:34 PDT 2015


Author: sanjoy
Date: Mon May 11 13:49:34 2015
New Revision: 237009

URL: http://llvm.org/viewvc/llvm-project?rev=237009&view=rev
Log:
[RewriteStatepointsForGC] Fix a bug on creating gc_relocate for pointer to vector of pointers

Summary:
In RewriteStatepointsForGC pass, we create a gc_relocate intrinsic for
each relocated pointer, and the gc_relocate has the same type with the
pointer. During the creation of gc_relocate intrinsic, llvm requires to
mangle its type. However, llvm does not support mangling of all possible
types. RewriteStatepointsForGC will hit an assertion failure when it
tries to create a gc_relocate for pointer to vector of pointers because
mangling for vector of pointers is not supported.

This patch changes the way RewriteStatepointsForGC pass creates
gc_relocate. For each relocated pointer, we erase the type of pointers
and create an unified gc_relocate of type i8 addrspace(1)*. Then a
bitcast is inserted to convert the gc_relocate to the correct type. In
this way, gc_relocate does not need to deal with different types of
pointers and the unsupported type mangling is no longer a problem. This
change would also ease further merge when LLVM erases types of pointers
and introduces an unified pointer type.

Some minor changes are also introduced to gc_relocate related part in
InstCombineCalls, CodeGenPrepare, and Verifier accordingly.

Patch by Chen Li!

Reviewers: reames, AndyAyers, sanjoy

Reviewed By: sanjoy

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D9592

Added:
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll
Modified:
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/live-vector.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/preprocess.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll
    llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocation.ll

Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Mon May 11 13:49:34 2015
@@ -600,13 +600,51 @@ simplifyRelocatesOffABase(IntrinsicInst
     // Create a Builder and replace the target callsite with a gep
     IRBuilder<> Builder(ToReplace);
     Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
+
+    // If gc_relocate does not match the actual type, cast it to the right type.
+    // In theory, there must be a bitcast after gc_relocate if the type does not
+    // match, and we should reuse it to get the derived pointer. But it could be
+    // cases like this:
+    // bb1:
+    //  ...
+    //  %g1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(...)
+    //  br label %merge
+    //
+    // bb2:
+    //  ...
+    //  %g2 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(...)
+    //  br label %merge
+    //
+    // merge:
+    //  %p1 = phi i8 addrspace(1)* [ %g1, %bb1 ], [ %g2, %bb2 ]
+    //  %cast = bitcast i8 addrspace(1)* %p1 in to i32 addrspace(1)*
+    //
+    // In this case, we can not find the bitcast any more. So we insert a new bitcast
+    // no matter there is already one or not. In this way, we can handle all cases, and
+    // the extra bitcast should be optimized away in later passes.
+    Instruction *ActualRelocatedBase = RelocatedBase;
+    if (RelocatedBase->getType() != Base->getType()) {
+      ActualRelocatedBase =
+          cast<Instruction>(Builder.CreateBitCast(RelocatedBase, Base->getType()));
+      ActualRelocatedBase->removeFromParent();
+      ActualRelocatedBase->insertAfter(cast<Instruction>(RelocatedBase));
+    }
     Value *Replacement = Builder.CreateGEP(
-        Derived->getSourceElementType(), RelocatedBase, makeArrayRef(OffsetV));
+        Derived->getSourceElementType(), ActualRelocatedBase, makeArrayRef(OffsetV));
     Instruction *ReplacementInst = cast<Instruction>(Replacement);
     ReplacementInst->removeFromParent();
-    ReplacementInst->insertAfter(RelocatedBase);
+    ReplacementInst->insertAfter(ActualRelocatedBase);
     Replacement->takeName(ToReplace);
-    ToReplace->replaceAllUsesWith(Replacement);
+    // If the newly generated derived pointer's type does not match the original derived
+    // pointer's type, cast the new derived pointer to match it. Same reasoning as above.
+    Instruction *ActualReplacement = ReplacementInst;
+    if (ReplacementInst->getType() != ToReplace->getType()) {
+      ActualReplacement =
+          cast<Instruction>(Builder.CreateBitCast(ReplacementInst, ToReplace->getType()));
+      ActualReplacement->removeFromParent();
+      ActualReplacement->insertAfter(ReplacementInst);
+    }
+    ToReplace->replaceAllUsesWith(ActualReplacement);
     ToReplace->eraseFromParent();
 
     MadeChange = true;

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon May 11 13:49:34 2015
@@ -3384,10 +3384,8 @@ void Verifier::visitIntrinsicFunctionCal
            "'gc parameters' section of the statepoint call",
            &CI);
 
-    // Assert that the result type matches the type of the relocated pointer
-    GCRelocateOperands Operands(&CI);
-    Assert(Operands.getDerivedPtr()->getType() == CI.getType(),
-           "gc.relocate: relocating a pointer shouldn't change its type", &CI);
+    // gc_relocate does not need to be the same type as the relocated pointer.
+    // It can casted to the correct type later if it's desired
     break;
   }
   };

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon May 11 13:49:34 2015
@@ -1202,6 +1202,7 @@ Instruction *InstCombiner::visitCallInst
     // preserve relocation semantics.
     GCRelocateOperands Operands(II);
     Value *DerivedPtr = Operands.getDerivedPtr();
+    auto *GCRelocateType = cast<PointerType>(II->getType());
 
     // Remove the relocation if unused, note that this check is required
     // to prevent the cases below from looping forever.
@@ -1212,14 +1213,18 @@ Instruction *InstCombiner::visitCallInst
     // TODO: provide a hook for this in GCStrategy.  This is clearly legal for
     // most practical collectors, but there was discussion in the review thread
     // about whether it was legal for all possible collectors.
-    if (isa<UndefValue>(DerivedPtr))
-      return ReplaceInstUsesWith(*II, DerivedPtr);
+    if (isa<UndefValue>(DerivedPtr)) {
+      // gc_relocate is uncasted. Use undef of gc_relocate's type to replace it.
+      return ReplaceInstUsesWith(*II, UndefValue::get(GCRelocateType));
+    }
 
     // The relocation of null will be null for most any collector.
     // TODO: provide a hook for this in GCStrategy.  There might be some weird
     // collector this property does not hold for.
-    if (isa<ConstantPointerNull>(DerivedPtr))
-      return ReplaceInstUsesWith(*II, DerivedPtr);
+    if (isa<ConstantPointerNull>(DerivedPtr)) {
+      // gc_relocate is uncasted. Use null-pointer of gc_relocate's type to replace it.
+      return ReplaceInstUsesWith(*II, ConstantPointerNull::get(GCRelocateType));
+    }
 
     // isKnownNonNull -> nonnull attribute
     if (isKnownNonNull(DerivedPtr))

Modified: llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp Mon May 11 13:49:34 2015
@@ -1075,7 +1075,10 @@ static void CreateGCRelocates(ArrayRef<l
     // the IR, but removes the need for argument bitcasts which shrinks the IR
     // greatly and makes it much more readable.
     SmallVector<Type *, 1> types;                 // one per 'any' type
-    types.push_back(liveVariables[i]->getType()); // result type
+    // All gc_relocate are set to i8 addrspace(1)* type. This could help avoid
+    // cases where the actual value's type mangling is not supported by llvm. A
+    // bitcast is added later to convert gc_relocate to the actual value's type.
+    types.push_back(Type::getInt8PtrTy(M->getContext(), 1));
     Value *gc_relocate_decl = Intrinsic::getDeclaration(
         M, Intrinsic::experimental_gc_relocate, types);
 
@@ -1342,8 +1345,16 @@ insertRelocationStores(iterator_range<Va
     Value *alloca = allocaMap[originalValue];
 
     // Emit store into the related alloca
-    StoreInst *store = new StoreInst(relocatedValue, alloca);
-    store->insertAfter(relocatedValue);
+    // All gc_relocate are i8 addrspace(1)* typed, and it must be bitcasted to
+    // the correct type according to alloca.
+    assert(relocatedValue->getNextNode() && "Should always have one since it's not a terminator");
+    IRBuilder<> Builder(relocatedValue->getNextNode());
+    Value *CastedRelocatedValue =
+        Builder.CreateBitCast(relocatedValue, cast<AllocaInst>(alloca)->getAllocatedType(),
+        relocatedValue->hasName() ? relocatedValue->getName() + ".casted" : "");
+
+    StoreInst *store = new StoreInst(CastedRelocatedValue, alloca);
+    store->insertAfter(cast<Instruction>(CastedRelocatedValue));
 
 #ifndef NDEBUG
     visitedLiveValues.insert(originalValue);

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers-11.ll Mon May 11 13:49:34 2015
@@ -12,11 +12,11 @@ entry:
 loop:                                             ; preds = %loop, %entry
 ; CHECK-LABEL: loop:
 ; CHECK: phi i64 addrspace(1)*
-; CHECK-DAG:  [ %base_obj.relocated, %loop ] 
+; CHECK-DAG:  [ %base_obj.relocated.casted, %loop ] 
 ; CHECK-DAG:  [ %base_obj, %entry ]
 ; CHECK:  %current = phi i64 addrspace(1)* 
 ; CHECK-DAG:  [ %obj, %entry ]
-; CHECK-DAG:  [ %next.relocated, %loop ]
+; CHECK-DAG:  [ %next.relocated.casted, %loop ]
   %current = phi i64 addrspace(1)* [ %obj, %entry ], [ %next, %loop ]
   %next = getelementptr i64, i64 addrspace(1)* %current, i32 1
   %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers.ll?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/base-pointers.ll Mon May 11 13:49:34 2015
@@ -13,7 +13,7 @@ entry:
 
 loop:
 ; CHECK: phi i64 addrspace(1)* 
-; CHECK-DAG: [ %obj.relocated, %loop ]
+; CHECK-DAG: [ %obj.relocated.casted, %loop ]
 ; CHECK-DAG: [ %obj, %entry ]
   call void @use_obj(i64 addrspace(1)* %obj)
   %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
@@ -78,7 +78,7 @@ loop:
 ; CHECK-DAG: [ %base_obj, %entry ]
 ; Given the two selects are equivelent, so are their base phis - ideally,
 ; we'd have commoned these, but that's a missed optimization, not correctness.
-; CHECK-DAG: [ [[DISCARD:%base_select.*.relocated]], %loop ]
+; CHECK-DAG: [ [[DISCARD:%base_select.*.relocated.casted]], %loop ]
 ; CHECK-NOT: base_phi2
 ; CHECK: next = select
 ; CHECK: base_select

Added: llvm/trunk/test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll?rev=237009&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll (added)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/gc_relocate_creation.ll Mon May 11 13:49:34 2015
@@ -0,0 +1,20 @@
+; RUN: opt %s -rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
+; This test is to verify gc.relocate can handle pointer to vector of
+; pointers (<2 x i32 addrspace(1)*> addrspace(1)* in this case).
+; The old scheme to create a gc.relocate of <2 x i32 addrspace(1)*> addrspace(1)*
+; type will fail because llvm does not support mangling vector of pointers.
+; The new scheme will create all gc.relocate to i8 addrspace(1)* type and
+; then bitcast to the correct type.
+
+declare void @foo()
+declare void @use(...)
+declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
+
+define void @test1(<2 x i32 addrspace(1)*> addrspace(1)* %obj) gc "statepoint-example" {
+entry:
+  %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
+; CHECK: %obj.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %safepoint_token, i32 5, i32 5)
+; CHECK-NEXT:  %obj.relocated.casted = bitcast i8 addrspace(1)* %obj.relocated to <2 x i32 addrspace(1)*> addrspace(1)*
+  call void (...) @use(<2 x i32 addrspace(1)*> addrspace(1)* %obj)
+  ret void
+}
\ No newline at end of file

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/live-vector.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/live-vector.ll?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/live-vector.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/live-vector.ll Mon May 11 13:49:34 2015
@@ -7,7 +7,8 @@ define i64 addrspace(1)* @test(i64 addrs
 ; CHECK-LABEL: test
 ; CHECK: gc.statepoint
 ; CHECK-NEXT: gc.relocate
-; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
 entry:
   %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
   ret i64 addrspace(1)* %obj
@@ -20,10 +21,12 @@ define <2 x i64 addrspace(1)*> @test2(<2
 ; CHECK-NEXT: extractelement
 ; CHECK-NEXT: gc.statepoint
 ; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: insertelement
 ; CHECK-NEXT: insertelement
-; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %5
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
 entry:
   %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
   ret <2 x i64 addrspace(1)*> %obj
@@ -37,10 +40,12 @@ define <2 x i64 addrspace(1)*> @test3(<2
 ; CHECK-NEXT: extractelement
 ; CHECK-NEXT: gc.statepoint
 ; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: insertelement
 ; CHECK-NEXT: insertelement
-; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %5
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
 entry:
   %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
   %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
@@ -63,19 +68,23 @@ entry:
 
 ; CHECK-LABEL: normal_return:
 ; CHECK: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: insertelement
 ; CHECK-NEXT: insertelement
-; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %6
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %8
 normal_return:                                    ; preds = %entry
   ret <2 x i64 addrspace(1)*> %obj
 
 ; CHECK-LABEL: exceptional_return:
 ; CHECK: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: insertelement
 ; CHECK-NEXT: insertelement
-; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %10
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %14
 exceptional_return:                               ; preds = %entry
   %landing_pad4 = landingpad { i8*, i32 } personality i32 ()* @fake_personality_function
           cleanup

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll Mon May 11 13:49:34 2015
@@ -13,7 +13,8 @@ entry:
 taken:
 ; CHECK-LABEL: taken:
 ; CHECK-NEXT: gc.statepoint
-; CHECK-NEXT: %obj.relocated = call coldcc i64 addrspace(1)*
+; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: br label %merge
   call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
   br label %merge
@@ -21,14 +22,15 @@ taken:
 untaken:
 ; CHECK-LABEL: untaken:
 ; CHECK-NEXT: gc.statepoint
-; CHECK-NEXT: %obj.relocated1 = call coldcc i64 addrspace(1)*
+; CHECK-NEXT: %obj.relocated1 = call coldcc i8 addrspace(1)*
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: br label %merge
   call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
   br label %merge
 
 merge:
 ; CHECK-LABEL: merge:
-; CHECK-NEXT: %.0 = phi i64 addrspace(1)* [ %obj.relocated, %taken ], [ %obj.relocated1, %untaken ]
+; CHECK-NEXT: %.0 = phi i64 addrspace(1)* [ %obj.relocated.casted, %taken ], [ %obj.relocated1.casted, %untaken ]
 ; CHECK-NEXT: ret i64 addrspace(1)* %.0
   ret i64 addrspace(1)* %obj
 }
@@ -48,7 +50,8 @@ taken:
 ; CHECK-NEXT:  %obj = load
 ; CHECK-NEXT:  gc.statepoint
 ; CHECK-NEXT:  gc.relocate
-; CHECK-NEXT:  ret i64 addrspace(1)* %obj.relocated
+; CHECK-NEXT: bitcast
+; CHECK-NEXT:  ret i64 addrspace(1)* %obj.relocated.casted
 
   %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
   call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
@@ -70,7 +73,8 @@ taken:
 ; CHECK-NEXT: gc.statepoint
 ; CHECK-NEXT: %obj = load
 ; CHECK-NEXT: gc.statepoint
-; CHECK-NEXT: %obj.relocated = call coldcc i64 addrspace(1)*
+; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: br label %merge
   call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
   %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc
@@ -97,13 +101,17 @@ entry:
 ; CHECK-LABEL: entry:
 ; CHECK-NEXT:  %derived = getelementptr
 ; CHECK-NEXT:  gc.statepoint
-; CHECK-NEXT:  %derived.relocated = 
+; CHECK-NEXT:  %derived.relocated =
+; CHECK-NEXT:  bitcast 
 ; CHECK-NEXT:  %obj.relocated =
+; CHECK-NEXT:  bitcast
 ; CHECK-NEXT:  gc.statepoint
-; CHECK-NEXT:  %derived.relocated1 = 
+; CHECK-NEXT:  %derived.relocated1 =
+; CHECK-NEXT:  bitcast 
 ; Note: It's legal to relocate obj again, but not strictly needed
 ; CHECK-NEXT:  %obj.relocated2 =
-; CHECK-NEXT:  ret i64 addrspace(1)* %derived.relocated1
+; CHECK-NEXT:  bitcast
+; CHECK-NEXT:  ret i64 addrspace(1)* %derived.relocated1.casted
 ; 
   %derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8
   call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
@@ -125,7 +133,8 @@ entry:
 taken:
 ; CHECK-LABEL: taken:
 ; CHECK-NEXT: gc.statepoint
-; CHECK-NEXT: %obj.relocated = call coldcc i64 addrspace(1)*
+; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: br label %merge
   call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
   br label %merge

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/preprocess.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/preprocess.ll?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/preprocess.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/preprocess.ll Mon May 11 13:49:34 2015
@@ -13,8 +13,9 @@ next:
 ; CHECK-LABEL: next:
 ; CHECK-NEXT: gc.statepoint
 ; CHECK-NEXT: gc.relocate
-; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated)
-; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated)
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
+; CHECK-NEXT: @consume(i64 addrspace(1)* %obj.relocated.casted)
   %obj2 = phi i64 addrspace(1)* [ %obj, %entry ]
   call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0, i32 0)
   call void (...) @consume(i64 addrspace(1)* %obj2)

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocate_invoke_result.ll Mon May 11 13:49:34 2015
@@ -23,7 +23,8 @@ unwind_dest:
 normal_dest:
 ;; CHECK-LABEL: normal_dest:
 ;; CHECK-NEXT: gc.statepoint
-;; CHECK-NEXT: %obj.relocated = call coldcc i64* addrspace(1)*                                      
+;; CHECK-NEXT: %obj.relocated = call coldcc i8 addrspace(1)*  
+;; CHECK-NEXT: bitcast                                    
   %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @gc_call, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
   ret i64* addrspace(1)* %obj
 }

Modified: llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocation.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocation.ll?rev=237009&r1=237008&r2=237009&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocation.ll (original)
+++ llvm/trunk/test/Transforms/RewriteStatepointsForGC/relocation.ll Mon May 11 13:49:34 2015
@@ -14,7 +14,7 @@ entry:
 
 joint:
 ; CHECK-LABEL: joint:
-; CHECK: %phi1 = phi i64 addrspace(1)* [ %obj.relocated, %entry ], [ %obj3, %joint2 ]
+; CHECK: %phi1 = phi i64 addrspace(1)* [ %obj.relocated.casted, %entry ], [ %obj3, %joint2 ]
   %phi1 = phi i64 addrspace(1)* [ %obj, %entry ], [ %obj3, %joint2 ]
   br i1 %condition, label %use, label %joint2
 
@@ -23,8 +23,8 @@ use:
 
 joint2:
 ; CHECK-LABEL: joint2:
-; CHECK: %phi2 = phi i64 addrspace(1)* [ %obj.relocated, %use ], [ %obj2.relocated, %joint ]
-; CHECK: %obj3 = getelementptr i64, i64 addrspace(1)* %obj2.relocated, i32 1
+; CHECK: %phi2 = phi i64 addrspace(1)* [ %obj.relocated.casted, %use ], [ %obj2.relocated.casted, %joint ]
+; CHECK: %obj3 = getelementptr i64, i64 addrspace(1)* %obj2.relocated.casted, i32 1
   %phi2 = phi i64 addrspace(1)* [ %obj, %use ], [ %obj2, %joint ]
   %obj3 = getelementptr i64, i64 addrspace(1)* %obj2, i32 1
   br label %joint
@@ -45,9 +45,9 @@ entry:
 
 loop:
 ; CHECK: loop:
-; CHECK-DAG: [ %obj_init.relocated, %loop.backedge ]
+; CHECK-DAG: [ %obj_init.relocated.casted, %loop.backedge ]
 ; CHECK-DAG: [ %obj_init, %entry ]
-; CHECK-DAG: [ %obj.relocated, %loop.backedge ]
+; CHECK-DAG: [ %obj.relocated.casted, %loop.backedge ]
 ; CHECK-DAG: [ %obj, %entry ]
   %index = phi i32 [ 0, %entry ], [ %index.inc, %loop.backedge ]
 ; CHECK-NOT: %location = getelementptr i64, i64 addrspace(1)* %obj, i32 %index
@@ -108,6 +108,7 @@ entry:
 ; CHECK-LABEL: @test3
 ; CHECK: gc.statepoint
 ; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
 ; CHECK-NEXT: gc.statepoint
   %safepoint_token = call i32 (void (i64)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi64f(void (i64)* undef, i32 1, i32 0, i64 undef, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
   %safepoint_token1 = call i32 (i32 (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32p1i64f(i32 (i64 addrspace(1)*)* undef, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
@@ -262,10 +263,10 @@ callbb:
 
 join:
 ; CHECK-LABEL: join:
-; CHECK: phi i64 addrspace(1)* [ %obj.relocated, %callbb ], [ %obj, %entry ]
+; CHECK: phi i64 addrspace(1)* [ %obj.relocated.casted, %callbb ], [ %obj, %entry ]
 ; CHECK: phi i64 addrspace(1)* 
 ; CHECK-DAG: [ %obj, %entry ]
-; CHECK-DAG: [ %obj2.relocated, %callbb ]
+; CHECK-DAG: [ %obj2.relocated.casted, %callbb ]
   ; This is a phi outside the dominator region of the new defs inserted by
   ; the safepoint, BUT we can't stop the search here or we miss the second
   ; phi below.





More information about the llvm-commits mailing list