1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[rs4gc] don't duplicate existing values which are provably base pointers

RS4GC needs to rewrite the IR to ensure that every relocated pointer has an associated base pointer. The existing code isn't particularly smart about avoiding duplication of existing IR when it turns out the original pointer we were asked to materialize a base pointer for is itself a base pointer.

This patch adds a stage to the algorithm which prunes nodes proven (with a simple forward dataflow fixed point) to be base pointers from the list of nodes considered for duplication. This does require changing some of the later invariants slightly, that's probably the riskiest part of the change.

Differential Revision: D98122
This commit is contained in:
Philip Reames 2021-03-16 12:47:57 -07:00
parent 52b2bd3243
commit 93763f7273
10 changed files with 145 additions and 174 deletions

View File

@ -900,14 +900,51 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) {
}
#endif
// Iterate forward through the value graph pruning any node from the state
// list where all of the inputs are base pointers. The purpose of this is to
// reuse existing values when the derived pointer we were asked to materialize
// a base pointer for happens to be a base pointer itself. (Or a sub-graph
// feeding it does.)
SmallVector<Value *> ToRemove;
do {
ToRemove.clear();
for (auto Pair : States) {
Value *BDV = Pair.first;
auto canPruneInput = [&](Value *V) {
Value *BDV = findBaseOrBDV(V, Cache);
if (V->stripPointerCasts() != BDV)
return false;
// The assumption is that anything not in the state list is
// propagates a base pointer.
return States.count(BDV) == 0;
};
bool CanPrune = true;
visitBDVOperands(BDV, [&](Value *Op) {
CanPrune = CanPrune && canPruneInput(Op);
});
if (CanPrune)
ToRemove.push_back(BDV);
}
for (Value *V : ToRemove) {
States.erase(V);
// Cache the fact V is it's own base for later usage.
Cache[V] = V;
}
} while (!ToRemove.empty());
// Did we manage to prove that Def itself must be a base pointer?
if (!States.count(Def))
return Def;
// Return a phi state for a base defining value. We'll generate a new
// base state for known bases and expect to find a cached state otherwise.
auto GetStateForBDV = [&](Value *BaseValue, Value *Input) {
if (isKnownBaseResult(BaseValue) && areBothVectorOrScalar(BaseValue, Input))
return BDVState(BaseValue, BDVState::Base, BaseValue);
auto I = States.find(BaseValue);
assert(I != States.end() && "lookup failed!");
return I->second;
if (I != States.end())
return I->second;
assert(areBothVectorOrScalar(BaseValue, Input));
return BDVState(BaseValue, BDVState::Base, BaseValue);
};
bool Progress = true;
@ -1071,7 +1108,8 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) {
auto getBaseForInput = [&](Value *Input, Instruction *InsertPt) {
Value *BDV = findBaseOrBDV(Input, Cache);
Value *Base = nullptr;
if (isKnownBaseResult(BDV) && areBothVectorOrScalar(BDV, Input)) {
if (!States.count(BDV)) {
assert(areBothVectorOrScalar(BDV, Input));
Base = BDV;
} else {
// Either conflict or base.
@ -1203,14 +1241,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) {
<< (Cache.count(BDV) ? Cache[BDV]->getName().str() : "none")
<< " to: " << Base->getName() << "\n");
if (Cache.count(BDV)) {
assert(isKnownBaseResult(Base) &&
"must be something we 'know' is a base pointer");
// Once we transition from the BDV relation being store in the Cache to
// the base relation being stored, it must be stable
assert((!isKnownBaseResult(Cache[BDV]) || Cache[BDV] == Base) &&
"base relation should be stable");
}
Cache[BDV] = Base;
}
assert(Cache.count(Def));
@ -3016,11 +3046,7 @@ static void recomputeLiveInValues(GCPtrLivenessData &RevisedLivenessData,
// We may have base pointers which are now live that weren't before. We need
// to update the PointerToBase structure to reflect this.
for (auto V : Updated)
if (Info.PointerToBase.insert({V, V}).second) {
assert(isKnownBaseResult(V) &&
"Can't find base for unexpected live value!");
continue;
}
Info.PointerToBase.insert({V, V});
#ifndef NDEBUG
for (auto V : Updated)

View File

@ -18,11 +18,9 @@ define i8 addrspace(1)* @test(i8 addrspace(1)* %a) gc "statepoint-example" {
define i8 addrspace(1)* @test_select(i1 %c, i8 addrspace(1)* %a1, i8 addrspace(1)* %a2) gc "statepoint-example" {
; CHECK-LABEL: @test_select(
; CHECK-NEXT: [[SEL_BASE:%.*]] = select i1 [[C:%.*]], i8 addrspace(1)* [[A1:%.*]], i8 addrspace(1)* [[A2:%.*]], !is_base_value !0
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i8 addrspace(1)* [[A1]], i8 addrspace(1)* [[A2]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[SEL]], i8 addrspace(1)* [[SEL_BASE]]) ]
; CHECK-NEXT: [[SEL_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[SEL_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8 addrspace(1)* [[A1:%.*]], i8 addrspace(1)* [[A2:%.*]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[SEL]]) ]
; CHECK-NEXT: [[SEL_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret i8 addrspace(1)* [[SEL_RELOCATED]]
;
%sel = select i1 %c, i8 addrspace(1)* %a1, i8 addrspace(1)* %a2
@ -39,11 +37,9 @@ define i8 addrspace(1)* @test_phi1(i1 %c, i8 addrspace(1)* %a1, i8 addrspace(1)*
; CHECK: untaken:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[PHI_BASE:%.*]] = phi i8 addrspace(1)* [ [[A1:%.*]], [[TAKEN]] ], [ [[A2:%.*]], [[UNTAKEN]] ], !is_base_value !0
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[A1]], [[TAKEN]] ], [ [[A2]], [[UNTAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]], i8 addrspace(1)* [[PHI_BASE]]) ]
; CHECK-NEXT: [[PHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[PHI_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[A1:%.*]], [[TAKEN]] ], [ [[A2:%.*]], [[UNTAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]]) ]
; CHECK-NEXT: [[PHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret i8 addrspace(1)* [[PHI_RELOCATED]]
;
entry:
@ -81,13 +77,11 @@ define i8 addrspace(1)* @test_loop1(i1 %c, i8 addrspace(1)* %a1, i8 addrspace(1)
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[PHI_BASE:%.*]] = phi i8 addrspace(1)* [ [[A1:%.*]], [[ENTRY:%.*]] ], [ [[A2:%.*]], [[LOOP]] ], !is_base_value !0
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[A1]], [[ENTRY]] ], [ [[A2]], [[LOOP]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[A1:%.*]], [[ENTRY:%.*]] ], [ [[A2:%.*]], [[LOOP]] ]
; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]], i8 addrspace(1)* [[PHI_BASE]]) ]
; CHECK-NEXT: [[PHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[PHI_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]]) ]
; CHECK-NEXT: [[PHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret i8 addrspace(1)* [[PHI_RELOCATED]]
;
entry:
@ -106,15 +100,13 @@ define i8 addrspace(1)* @test_loop2(i1 %c, i8 addrspace(1)* %a1) gc "statepoint-
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[PHI_BASE:%.*]] = phi i8 addrspace(1)* [ [[A1:%.*]], [[ENTRY:%.*]] ], [ [[O2:%.*]], [[LOOP]] ], !is_base_value !0
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[A1]], [[ENTRY]] ], [ [[O2]], [[LOOP]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[A1:%.*]], [[ENTRY:%.*]] ], [ [[O2:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[ADDR:%.*]] = bitcast i8 addrspace(1)* [[PHI]] to i8 addrspace(1)* addrspace(1)*
; CHECK-NEXT: [[O2]] = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* [[ADDR]], align 8
; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]], i8 addrspace(1)* [[PHI_BASE]]) ]
; CHECK-NEXT: [[PHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[PHI_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]]) ]
; CHECK-NEXT: [[PHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret i8 addrspace(1)* [[PHI_RELOCATED]]
;
entry:
@ -171,11 +163,9 @@ define <2 x i8 addrspace(1)*> @test_vec_passthrough(<2 x i8 addrspace(1)*> %a) g
define <2 x i8 addrspace(1)*> @test_insert(i8 addrspace(1)* %a) gc "statepoint-example" {
; CHECK-LABEL: @test_insert(
; CHECK-NEXT: [[VEC_BASE:%.*]] = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* [[A:%.*]], i64 0, !is_base_value !0
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* [[A]], i64 0
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<2 x i8 addrspace(1)*> [[VEC]], <2 x i8 addrspace(1)*> [[VEC_BASE]]) ]
; CHECK-NEXT: [[VEC_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[VEC_BASE_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[VEC:%.*]] = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* [[A:%.*]], i64 0
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<2 x i8 addrspace(1)*> [[VEC]]) ]
; CHECK-NEXT: [[VEC_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x i8 addrspace(1)*> [[VEC_RELOCATED]]
;
%vec = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* %a, i64 0
@ -185,11 +175,9 @@ define <2 x i8 addrspace(1)*> @test_insert(i8 addrspace(1)* %a) gc "statepoint-e
define i8 addrspace(1)* @test_extract(<2 x i8 addrspace(1)*> %a) gc "statepoint-example" {
; CHECK-LABEL: @test_extract(
; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <2 x i8 addrspace(1)*> [[A:%.*]], i64 0, !is_base_value !0
; CHECK-NEXT: [[EE:%.*]] = extractelement <2 x i8 addrspace(1)*> [[A]], i64 0
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[EE]], i8 addrspace(1)* [[BASE_EE]]) ]
; CHECK-NEXT: [[EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[BASE_EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[EE:%.*]] = extractelement <2 x i8 addrspace(1)*> [[A:%.*]], i64 0
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[EE]]) ]
; CHECK-NEXT: [[EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret i8 addrspace(1)* [[EE_RELOCATED]]
;
%ee = extractelement <2 x i8 addrspace(1)*> %a, i64 0
@ -200,9 +188,8 @@ define i8 addrspace(1)* @test_extract(<2 x i8 addrspace(1)*> %a) gc "statepoint-
define <2 x i8 addrspace(1)*> @test_shuffle(<2 x i8 addrspace(1)*> %a1) gc "statepoint-example" {
; CHECK-LABEL: @test_shuffle(
; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[A1:%.*]], <2 x i8 addrspace(1)*> [[A1]], <2 x i32> zeroinitializer
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<2 x i8 addrspace(1)*> [[RES]], <2 x i8 addrspace(1)*> [[A1]]) ]
; CHECK-NEXT: [[RES_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[A1_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<2 x i8 addrspace(1)*> [[RES]]) ]
; CHECK-NEXT: [[RES_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x i8 addrspace(1)*> [[RES_RELOCATED]]
;
%res = shufflevector <2 x i8 addrspace(1)*> %a1, <2 x i8 addrspace(1)*> %a1, <2 x i32> zeroinitializer
@ -212,11 +199,9 @@ define <2 x i8 addrspace(1)*> @test_shuffle(<2 x i8 addrspace(1)*> %a1) gc "stat
define <2 x i8 addrspace(1)*> @test_shuffle2(<2 x i8 addrspace(1)*> %a1, <2 x i8 addrspace(1)*> %a2) gc "statepoint-example" {
; CHECK-LABEL: @test_shuffle2(
; CHECK-NEXT: [[RES_BASE:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[A1:%.*]], <2 x i8 addrspace(1)*> [[A2:%.*]], <2 x i32> zeroinitializer, !is_base_value !0
; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[A1]], <2 x i8 addrspace(1)*> [[A2]], <2 x i32> zeroinitializer
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<2 x i8 addrspace(1)*> [[RES]], <2 x i8 addrspace(1)*> [[RES_BASE]]) ]
; CHECK-NEXT: [[RES_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[RES_BASE_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[A1:%.*]], <2 x i8 addrspace(1)*> [[A2:%.*]], <2 x i32> zeroinitializer
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<2 x i8 addrspace(1)*> [[RES]]) ]
; CHECK-NEXT: [[RES_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <2 x i8 addrspace(1)*> [[RES_RELOCATED]]
;
%res = shufflevector <2 x i8 addrspace(1)*> %a1, <2 x i8 addrspace(1)*> %a2, <2 x i32> zeroinitializer
@ -226,11 +211,9 @@ define <2 x i8 addrspace(1)*> @test_shuffle2(<2 x i8 addrspace(1)*> %a1, <2 x i8
define <4 x i8 addrspace(1)*> @test_shuffle_concat(<2 x i8 addrspace(1)*> %a1, <2 x i8 addrspace(1)*> %a2) gc "statepoint-example" {
; CHECK-LABEL: @test_shuffle_concat(
; CHECK-NEXT: [[RES_BASE:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[A1:%.*]], <2 x i8 addrspace(1)*> [[A2:%.*]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>, !is_base_value !0
; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[A1]], <2 x i8 addrspace(1)*> [[A2]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<4 x i8 addrspace(1)*> [[RES]], <4 x i8 addrspace(1)*> [[RES_BASE]]) ]
; CHECK-NEXT: [[RES_RELOCATED:%.*]] = call coldcc <4 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v4p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[RES_BASE_RELOCATED:%.*]] = call coldcc <4 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v4p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[A1:%.*]], <2 x i8 addrspace(1)*> [[A2:%.*]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<4 x i8 addrspace(1)*> [[RES]]) ]
; CHECK-NEXT: [[RES_RELOCATED:%.*]] = call coldcc <4 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v4p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: ret <4 x i8 addrspace(1)*> [[RES_RELOCATED]]
;
%res = shufflevector <2 x i8 addrspace(1)*> %a1, <2 x i8 addrspace(1)*> %a2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
@ -238,23 +221,40 @@ define <4 x i8 addrspace(1)*> @test_shuffle_concat(<2 x i8 addrspace(1)*> %a1, <
ret <4 x i8 addrspace(1)*> %res
}
; TODO: Special case worth handling - we interpret the shuffle as if we need
; to select the base pointers from either input when the mask is known.
define <2 x i8 addrspace(1)*> @test_shuffle_broadcast(i8 addrspace(1)* %a) gc "statepoint-example" {
; CHECK-LABEL: @test_shuffle_broadcast(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[IE:%.*]] = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* [[A:%.*]], i64 0
; CHECK-NEXT: [[BROADCAST_BASE:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[IE]], <2 x i8 addrspace(1)*> zeroinitializer, <2 x i32> zeroinitializer, !is_base_value !0
; CHECK-NEXT: [[BROADCAST:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[IE]], <2 x i8 addrspace(1)*> undef, <2 x i32> zeroinitializer
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(<2 x i8 addrspace(1)*> [[BROADCAST]], <2 x i8 addrspace(1)*> [[BROADCAST_BASE]]) ]
; CHECK-NEXT: [[BROADCAST_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[BROADCAST_BASE_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: ret <2 x i8 addrspace(1)*> [[BROADCAST_RELOCATED]]
;
entry:
%ie = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* %a, i64 0
%broadcast = shufflevector <2 x i8 addrspace(1)*> %ie, <2 x i8 addrspace(1)*> undef, <2 x i32> zeroinitializer
call void @foo()
ret <2 x i8 addrspace(1)*> %broadcast
}
; Show a case where only a portion of the sub-graph propagates base pointers.
define i8 @test_subgraph(i1 %c, i8 addrspace(1)* %a1, i8 addrspace(1)* %a2) gc "statepoint-example" {
; CHECK-LABEL: @test_subgraph(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEL_BASE:%.*]] = select i1 [[C:%.*]], i8 addrspace(1)* [[A1:%.*]], i8 addrspace(1)* [[A2:%.*]], !is_base_value !0
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i8 addrspace(1)* [[A1]], i8 addrspace(1)* [[A2]]
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8 addrspace(1)* [[A1:%.*]], i8 addrspace(1)* [[A2:%.*]]
; CHECK-NEXT: br i1 [[C]], label [[TAKEN:%.*]], label [[MERGE:%.*]]
; CHECK: taken:
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, i8 addrspace(1)* [[SEL]], i64 8
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[PHI_BASE:%.*]] = phi i8 addrspace(1)* [ [[SEL_BASE]], [[TAKEN]] ], [ [[SEL_BASE]], [[ENTRY:%.*]] ], !is_base_value !0
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[GEP]], [[TAKEN]] ], [ [[SEL]], [[ENTRY]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]], i8 addrspace(1)* [[PHI_BASE]]) ]
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[GEP]], [[TAKEN]] ], [ [[SEL]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[PHI]], i8 addrspace(1)* [[SEL]]) ]
; CHECK-NEXT: [[PHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[PHI_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[SEL_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[RES:%.*]] = load i8, i8 addrspace(1)* [[PHI_RELOCATED]], align 1
; CHECK-NEXT: ret i8 [[RES]]
;
@ -275,24 +275,19 @@ merge:
define i8 @test_subgraph2(i1 %c, i8 addrspace(1)* %a1, i8 addrspace(1)* %a2) gc "statepoint-example" {
; CHECK-LABEL: @test_subgraph2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEL_BASE:%.*]] = select i1 [[C:%.*]], i8 addrspace(1)* [[A1:%.*]], i8 addrspace(1)* [[A2:%.*]], !is_base_value !0
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i8 addrspace(1)* [[A1]], i8 addrspace(1)* [[A2]]
; CHECK-NEXT: [[IE_BASE:%.*]] = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* [[SEL_BASE]], i64 0, !is_base_value !0
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8 addrspace(1)* [[A1:%.*]], i8 addrspace(1)* [[A2:%.*]]
; CHECK-NEXT: [[IE:%.*]] = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* [[SEL]], i64 0
; CHECK-NEXT: [[BROADCAST_BASE:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[IE_BASE]], <2 x i8 addrspace(1)*> zeroinitializer, <2 x i32> zeroinitializer, !is_base_value !0
; CHECK-NEXT: [[BROADCAST:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[IE]], <2 x i8 addrspace(1)*> undef, <2 x i32> zeroinitializer
; CHECK-NEXT: [[EE_BASE:%.*]] = extractelement <2 x i8 addrspace(1)*> [[BROADCAST_BASE]], i32 1, !is_base_value !0
; CHECK-NEXT: [[BROADCAST:%.*]] = shufflevector <2 x i8 addrspace(1)*> [[IE]], <2 x i8 addrspace(1)*> [[IE]], <2 x i32> zeroinitializer
; CHECK-NEXT: [[EE:%.*]] = extractelement <2 x i8 addrspace(1)*> [[BROADCAST]], i32 1
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[EE]], i8 addrspace(1)* [[EE_BASE]]) ]
; CHECK-NEXT: [[EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[EE_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* [[EE]]) ]
; CHECK-NEXT: [[EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[RES:%.*]] = load i8, i8 addrspace(1)* [[EE_RELOCATED]], align 1
; CHECK-NEXT: ret i8 [[RES]]
;
entry:
%sel = select i1 %c, i8 addrspace(1)* %a1, i8 addrspace(1)* %a2
%ie = insertelement <2 x i8 addrspace(1)*> zeroinitializer, i8 addrspace(1)* %sel, i64 0
%broadcast = shufflevector <2 x i8 addrspace(1)*> %ie, <2 x i8 addrspace(1)*> undef, <2 x i32> zeroinitializer
%broadcast = shufflevector <2 x i8 addrspace(1)*> %ie, <2 x i8 addrspace(1)*> %ie, <2 x i32> zeroinitializer
%ee = extractelement <2 x i8 addrspace(1)*> %broadcast, i32 1
call void @foo()
%res = load i8, i8 addrspace(1)* %ee
@ -300,5 +295,4 @@ entry:
}
declare void @foo()

View File

@ -27,12 +27,9 @@ define void @test(i32 %condition) gc "statepoint-example" {
; CHECK: dest_c:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[OBJ_TO_CONSUME_BASE:%.*]] = phi i64 addrspace(1)* [ [[TMP0]], [[DEST_A]] ], [ null, [[DEST_B]] ], [ null, [[DEST_C]] ], !is_base_value !0
; CHECK-NEXT: [[OBJ_TO_CONSUME:%.*]] = phi i64 addrspace(1)* [ [[TMP0]], [[DEST_A]] ], [ null, [[DEST_B]] ], [ null, [[DEST_C]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 2882400000, i32 0, void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* [[OBJ_TO_CONSUME]], i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[OBJ_TO_CONSUME_BASE]], i64 addrspace(1)* [[OBJ_TO_CONSUME]]) ]
; CHECK-NEXT: [[OBJ_TO_CONSUME_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_TO_CONSUME_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_TO_CONSUME_BASE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_TO_CONSUME_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 0, i32 1)
; CHECK-NEXT: [[STATEPOINT_TOKEN1:%.*]] = call token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 2882400000, i32 0, void (i64 addrspace(1)*)* @consume_obj, i32 1, i32 0, i64 addrspace(1)* [[OBJ_TO_CONSUME]], i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[OBJ_TO_CONSUME]]) ]
; CHECK-NEXT: [[OBJ_TO_CONSUME_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN1]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_TO_CONSUME_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_TO_CONSUME_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: br label [[MERGE_SPLIT:%.*]]
; CHECK: merge.split:

View File

@ -41,7 +41,6 @@ define i64 addrspace(1)* @test1(i32 %caller, i8 addrspace(1)* %a, i8 addrspace(1
; CHECK-NEXT: br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
; CHECK: left:
; CHECK-NEXT: [[A_CAST:%.*]] = bitcast i8 addrspace(1)* [[A:%.*]] to i64 addrspace(1)*
; CHECK-NEXT: [[CAST:%.*]] = bitcast i8 addrspace(1)* [[A]] to i64 addrspace(1)*
; CHECK-NEXT: switch i32 [[UNKNOWN:%.*]], label [[RIGHT]] [
; CHECK-NEXT: i32 0, label [[MERGE:%.*]]
; CHECK-NEXT: i32 1, label [[MERGE]]
@ -49,16 +48,12 @@ define i64 addrspace(1)* @test1(i32 %caller, i8 addrspace(1)* %a, i8 addrspace(1
; CHECK-NEXT: ]
; CHECK: right:
; CHECK-NEXT: [[B_CAST:%.*]] = bitcast i8 addrspace(1)* [[B:%.*]] to i64 addrspace(1)*
; CHECK-NEXT: [[CAST1:%.*]] = bitcast i8 addrspace(1)* [[B]] to i64 addrspace(1)*
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[VALUE_BASE:%.*]] = phi i64 addrspace(1)* [ [[CAST]], [[LEFT]] ], [ [[CAST]], [[LEFT]] ], [ [[CAST]], [[LEFT]] ], [ [[CAST1]], [[RIGHT]] ], !is_base_value !0
; CHECK-NEXT: [[VALUE:%.*]] = phi i64 addrspace(1)* [ [[A_CAST]], [[LEFT]] ], [ [[A_CAST]], [[LEFT]] ], [ [[A_CAST]], [[LEFT]] ], [ [[B_CAST]], [[RIGHT]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 2882400000, i32 0, void (i64 addrspace(1)*)* @parse_point, i32 1, i32 0, i64 addrspace(1)* [[VALUE]], i32 0, i32 0) [ "deopt"(i32 0, i32 0, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[VALUE]], i64 addrspace(1)* [[VALUE_BASE]]) ]
; CHECK-NEXT: [[VALUE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 2882400000, i32 0, void (i64 addrspace(1)*)* @parse_point, i32 1, i32 0, i64 addrspace(1)* [[VALUE]], i32 0, i32 0) [ "deopt"(i32 0, i32 0, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[VALUE]]) ]
; CHECK-NEXT: [[VALUE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[VALUE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[VALUE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[VALUE_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[VALUE_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[VALUE_BASE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[VALUE_RELOCATED_CASTED]]
;
entry:
@ -146,13 +141,10 @@ define i64 addrspace(1)* @test3(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1
; CHECK: taken:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[BDV_BASE:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ2:%.*]], [[TAKEN]] ], !is_base_value !0
; CHECK-NEXT: [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ]], [[ENTRY]] ], [ [[OBJ2]], [[TAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BDV_BASE]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ2:%.*]], [[TAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[BDV_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[BDV_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_BASE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]
;
entry:
@ -175,11 +167,9 @@ define i64 addrspace(1)* @test4(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ]], [[TAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]
;
entry:
@ -199,15 +189,12 @@ define i64 addrspace(1)* @test5(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[MERGE:%.*]]
; CHECK: merge:
; CHECK-NEXT: [[BDV_BASE:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ2:%.*]], [[MERGE]] ], !is_base_value !0
; CHECK-NEXT: [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ]], [[ENTRY]] ], [ [[OBJ2]], [[MERGE]] ]
; CHECK-NEXT: [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ2:%.*]], [[MERGE]] ]
; CHECK-NEXT: br i1 [[CND:%.*]], label [[MERGE]], label [[NEXT:%.*]]
; CHECK: next:
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BDV_BASE]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[BDV_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[BDV_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_BASE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]
;
entry:

View File

@ -6,13 +6,10 @@
define i64 addrspace(1)* @test(<2 x i64 addrspace(1)*> %vec, i32 %idx) gc "statepoint-example" {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC:%.*]], i32 [[IDX:%.*]], !is_base_value !0
; CHECK-NEXT: [[OBJ:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[BASE_EE]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[OBJ:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC:%.*]], i32 [[IDX:%.*]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[BASE_EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[BASE_EE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASE_EE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]]
;
; Note that the second extractelement is actually redundant here. A correct output would
@ -34,25 +31,19 @@ define i64 addrspace(1)* @test2(<2 x i64 addrspace(1)*>* %ptr, i1 %cnd, i32 %idx
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR]], align 16
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[VEC_BASE:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ], !is_base_value !0
; CHECK-NEXT: [[VEC:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: br i1 [[CND]], label [[TAKEN2:%.*]], label [[UNTAKEN2:%.*]]
; CHECK: taken2:
; CHECK-NEXT: [[OBJ0_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 [[IDX1:%.*]], !is_base_value !0
; CHECK-NEXT: [[OBJ0:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX1]]
; CHECK-NEXT: [[OBJ0:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX1:%.*]]
; CHECK-NEXT: br label [[MERGE2:%.*]]
; CHECK: untaken2:
; CHECK-NEXT: [[OBJ1_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 [[IDX2:%.*]], !is_base_value !0
; CHECK-NEXT: [[OBJ1:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX2]]
; CHECK-NEXT: [[OBJ1:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX2:%.*]]
; CHECK-NEXT: br label [[MERGE2]]
; CHECK: merge2:
; CHECK-NEXT: [[OBJ_BASE:%.*]] = phi i64 addrspace(1)* [ [[OBJ0_BASE]], [[TAKEN2]] ], [ [[OBJ1_BASE]], [[UNTAKEN2]] ], !is_base_value !0
; CHECK-NEXT: [[OBJ:%.*]] = phi i64 addrspace(1)* [ [[OBJ0]], [[TAKEN2]] ], [ [[OBJ1]], [[UNTAKEN2]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[OBJ_BASE]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_BASE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]]
;
entry:
@ -282,13 +273,10 @@ define void @test9(<4 x i64 addrspace(1)*> %vec1, i64 %idx) gc "statepoint-examp
; CHECK-LABEL: @test9(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[VEC:%.*]] = shufflevector <4 x i64 addrspace(1)*> [[VEC1:%.*]], <4 x i64 addrspace(1)*> [[VEC1]], <2 x i32> <i32 0, i32 2>
; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <4 x i64 addrspace(1)*> [[VEC1]], i64 [[IDX:%.*]], !is_base_value !0
; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i64 [[IDX]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BASE_EE]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i64 [[IDX:%.*]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[BASE_EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[BASE_EE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASE_EE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: call void @use(i64 addrspace(1)* [[BDV_RELOCATED_CASTED]])
; CHECK-NEXT: ret void
;

View File

@ -8,13 +8,10 @@ define i64 addrspace(1)* @test(<2 x i64 addrspace(1)*> %vec, i32 %idx) gc "state
; be to reuse the existing obj as a base since it is actually a base pointer.
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC:%.*]], i32 [[IDX:%.*]], !is_base_value !0
; CHECK-NEXT: [[OBJ:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[BASE_EE]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[OBJ:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC:%.*]], i32 [[IDX:%.*]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[BASE_EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[BASE_EE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASE_EE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]]
;
entry:
@ -34,25 +31,19 @@ define i64 addrspace(1)* @test2(<2 x i64 addrspace(1)*>* %ptr, i1 %cnd, i32 %idx
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR]], align 16
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[VEC_BASE:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ], !is_base_value !0
; CHECK-NEXT: [[VEC:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: br i1 [[CND]], label [[TAKEN2:%.*]], label [[UNTAKEN2:%.*]]
; CHECK: taken2:
; CHECK-NEXT: [[OBJ0_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 [[IDX1:%.*]], !is_base_value !0
; CHECK-NEXT: [[OBJ0:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX1]]
; CHECK-NEXT: [[OBJ0:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX1:%.*]]
; CHECK-NEXT: br label [[MERGE2:%.*]]
; CHECK: untaken2:
; CHECK-NEXT: [[OBJ1_BASE:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC_BASE]], i32 [[IDX2:%.*]], !is_base_value !0
; CHECK-NEXT: [[OBJ1:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX2]]
; CHECK-NEXT: [[OBJ1:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i32 [[IDX2:%.*]]
; CHECK-NEXT: br label [[MERGE2]]
; CHECK: merge2:
; CHECK-NEXT: [[OBJ_BASE:%.*]] = phi i64 addrspace(1)* [ [[OBJ0_BASE]], [[TAKEN2]] ], [ [[OBJ1_BASE]], [[UNTAKEN2]] ], !is_base_value !0
; CHECK-NEXT: [[OBJ:%.*]] = phi i64 addrspace(1)* [ [[OBJ0]], [[TAKEN2]] ], [ [[OBJ1]], [[UNTAKEN2]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]], i64 addrspace(1)* [[OBJ_BASE]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i64 addrspace(1)* [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[OBJ_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[OBJ_BASE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: ret i64 addrspace(1)* [[OBJ_RELOCATED_CASTED]]
;
entry:
@ -282,13 +273,10 @@ define void @test9(<4 x i64 addrspace(1)*> %vec1, i64 %idx) gc "statepoint-examp
; CHECK-LABEL: @test9(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[VEC:%.*]] = shufflevector <4 x i64 addrspace(1)*> [[VEC1:%.*]], <4 x i64 addrspace(1)*> [[VEC1]], <2 x i32> <i32 0, i32 2>
; CHECK-NEXT: [[BASE_EE:%.*]] = extractelement <4 x i64 addrspace(1)*> [[VEC1]], i64 [[IDX:%.*]], !is_base_value !0
; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i64 [[IDX]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]], i64 addrspace(1)* [[BASE_EE]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[BDV:%.*]] = extractelement <2 x i64 addrspace(1)*> [[VEC]], i64 [[IDX:%.*]]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
; CHECK-NEXT: [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: [[BASE_EE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[BASE_EE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASE_EE_RELOCATED]] to i64 addrspace(1)*
; CHECK-NEXT: call void @use(i64 addrspace(1)* [[BDV_RELOCATED_CASTED]])
; CHECK-NEXT: ret void
;

View File

@ -112,13 +112,10 @@ define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR]], align 16
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[OBJ_BASE:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ], !is_base_value !0
; CHECK-NEXT: [[OBJ:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]], <2 x i64 addrspace(1)*> [[OBJ_BASE]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: [[OBJ_BASE_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_BASE_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_BASE_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
;
entry:

View File

@ -112,13 +112,10 @@ define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc
; CHECK-NEXT: [[OBJB:%.*]] = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* [[PTR]], align 16
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[OBJ_BASE:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ], !is_base_value !0
; CHECK-NEXT: [[OBJ:%.*]] = phi <2 x i64 addrspace(1)*> [ [[OBJA]], [[TAKEN]] ], [ [[OBJB]], [[UNTAKEN]] ]
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]], <2 x i64 addrspace(1)*> [[OBJ_BASE]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 0)
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(<2 x i64 addrspace(1)*> [[OBJ]]) ]
; CHECK-NEXT: [[OBJ_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[OBJ_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: [[OBJ_BASE_RELOCATED:%.*]] = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token [[STATEPOINT_TOKEN]], i32 1, i32 1)
; CHECK-NEXT: [[OBJ_BASE_RELOCATED_CASTED:%.*]] = bitcast <2 x i8 addrspace(1)*> [[OBJ_BASE_RELOCATED]] to <2 x i64 addrspace(1)*>
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> [[OBJ_RELOCATED_CASTED]]
;
entry:

View File

@ -375,13 +375,12 @@ define void @contains_basephi(i1 %cond) gc "statepoint-example" {
; CHECK: there:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[BASEPHI_BASE:%.*]] = phi i32 addrspace(1)* [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ], !is_base_value !0
; CHECK-NEXT: [[BASEPHI:%.*]] = phi i32 addrspace(1)* [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ]
; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI]], i32 15
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i32 addrspace(1)* [[BASEPHI_BASE]]) ]
; CHECK-NEXT: [[BASEPHI_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BASEPHI_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASEPHI_BASE_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI_BASE_RELOCATED_CASTED]], i32 15
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i32 addrspace(1)* [[BASEPHI]]) ]
; CHECK-NEXT: [[BASEPHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BASEPHI_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASEPHI_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI_RELOCATED_CASTED]], i32 15
; CHECK-NEXT: call void @use_obj32(i32 addrspace(1)* [[PTR_GEP_REMAT]])
; CHECK-NEXT: ret void
;
@ -419,17 +418,16 @@ define void @test_intersecting_chains_with_phi(i1 %cond) gc "statepoint-example"
; CHECK: there:
; CHECK-NEXT: br label [[MERGE]]
; CHECK: merge:
; CHECK-NEXT: [[BASEPHI_BASE:%.*]] = phi i32 addrspace(1)* [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ], !is_base_value !0
; CHECK-NEXT: [[BASEPHI:%.*]] = phi i32 addrspace(1)* [ [[BASE1]], [[HERE]] ], [ [[BASE2]], [[THERE]] ]
; CHECK-NEXT: [[PTR_GEP:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI]], i32 15
; CHECK-NEXT: [[PTR_CAST:%.*]] = bitcast i32 addrspace(1)* [[PTR_GEP]] to i64 addrspace(1)*
; CHECK-NEXT: [[PTR_CAST2:%.*]] = bitcast i32 addrspace(1)* [[PTR_GEP]] to i16 addrspace(1)*
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i32 addrspace(1)* [[BASEPHI_BASE]]) ]
; CHECK-NEXT: [[BASEPHI_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BASEPHI_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASEPHI_BASE_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: [[PTR_GEP_REMAT1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI_BASE_RELOCATED_CASTED]], i32 15
; CHECK-NEXT: [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(), "gc-live"(i32 addrspace(1)* [[BASEPHI]]) ]
; CHECK-NEXT: [[BASEPHI_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
; CHECK-NEXT: [[BASEPHI_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BASEPHI_RELOCATED]] to i32 addrspace(1)*
; CHECK-NEXT: [[PTR_GEP_REMAT1:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI_RELOCATED_CASTED]], i32 15
; CHECK-NEXT: [[PTR_CAST_REMAT:%.*]] = bitcast i32 addrspace(1)* [[PTR_GEP_REMAT1]] to i64 addrspace(1)*
; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI_BASE_RELOCATED_CASTED]], i32 15
; CHECK-NEXT: [[PTR_GEP_REMAT:%.*]] = getelementptr i32, i32 addrspace(1)* [[BASEPHI_RELOCATED_CASTED]], i32 15
; CHECK-NEXT: [[PTR_CAST2_REMAT:%.*]] = bitcast i32 addrspace(1)* [[PTR_GEP_REMAT]] to i16 addrspace(1)*
; CHECK-NEXT: call void @use_obj64(i64 addrspace(1)* [[PTR_CAST_REMAT]])
; CHECK-NEXT: call void @use_obj16(i16 addrspace(1)* [[PTR_CAST2_REMAT]])

View File

@ -14,10 +14,9 @@ define i32 addrspace(1)* @test1(i8 addrspace(1)* %base1, <2 x i64> %offsets) gc
; CHECK-NEXT: [[BASE21:%.*]] = call i8 addrspace(1)* @llvm.experimental.gc.result.p1i8(token [[STATEPOINT_TOKEN]])
; CHECK-NEXT: br label [[SECOND]]
; CHECK: second:
; CHECK-NEXT: [[PHI_BASE:%.*]] = phi i8 addrspace(1)* [ [[BASE1:%.*]], [[ENTRY:%.*]] ], [ [[BASE21]], [[FIRST]] ], !is_base_value !0
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[BASE1]], [[ENTRY]] ], [ [[BASE21]], [[FIRST]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi i8 addrspace(1)* [ [[BASE1:%.*]], [[ENTRY:%.*]] ], [ [[BASE21]], [[FIRST]] ]
; CHECK-NEXT: [[BASE_I32:%.*]] = bitcast i8 addrspace(1)* [[PHI]] to i32 addrspace(1)*
; CHECK-NEXT: [[CAST:%.*]] = bitcast i8 addrspace(1)* [[PHI_BASE]] to i32 addrspace(1)*
; CHECK-NEXT: [[CAST:%.*]] = bitcast i8 addrspace(1)* [[PHI]] to i32 addrspace(1)*
; CHECK-NEXT: [[DOTSPLATINSERT_BASE:%.*]] = insertelement <2 x i32 addrspace(1)*> zeroinitializer, i32 addrspace(1)* [[CAST]], i32 0, !is_base_value !0
; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i32 addrspace(1)*> poison, i32 addrspace(1)* [[BASE_I32]], i32 0
; CHECK-NEXT: [[DOTSPLAT_BASE:%.*]] = shufflevector <2 x i32 addrspace(1)*> [[DOTSPLATINSERT_BASE]], <2 x i32 addrspace(1)*> zeroinitializer, <2 x i32> zeroinitializer, !is_base_value !0