Skip to content

Commit 9e5604d

Browse files
author
Serguei Katkov
committed
[CGP] Fix the rematerialization of gc.relocates
If we want to substitute the relocation of derived pointer with gep of base then we must ensure that relocation of base dominates the relocation of derived pointer. Currently only check for basic block is present. However it is possible that both relocation are in the same basic block but relocation of derived pointer is defined earlier. The patch moves the relocation of base pointer right before relocation of derived pointer in this case. Reviewers: sanjoy,artagnon,igor-laevsky,reames Reviewed By: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D36462 llvm-svn: 311067
1 parent ed6a4ac commit 9e5604d

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,21 @@ static bool
948948
simplifyRelocatesOffABase(GCRelocateInst *RelocatedBase,
949949
const SmallVectorImpl<GCRelocateInst *> &Targets) {
950950
bool MadeChange = false;
951+
// We must ensure the relocation of derived pointer is defined after
952+
// relocation of base pointer. If we find a relocation corresponding to base
953+
// defined earlier than relocation of base then we move relocation of base
954+
// right before found relocation. We consider only relocation in the same
955+
// basic block as relocation of base. Relocations from other basic block will
956+
// be skipped by optimization and we do not care about them.
957+
for (auto R = RelocatedBase->getParent()->getFirstInsertionPt();
958+
&*R != RelocatedBase; ++R)
959+
if (auto RI = dyn_cast<GCRelocateInst>(R))
960+
if (RI->getStatepoint() == RelocatedBase->getStatepoint())
961+
if (RI->getBasePtrIndex() == RelocatedBase->getBasePtrIndex()) {
962+
RelocatedBase->moveBefore(RI);
963+
break;
964+
}
965+
951966
for (GCRelocateInst *ToReplace : Targets) {
952967
assert(ToReplace->getBasePtrIndex() == RelocatedBase->getBasePtrIndex() &&
953968
"Not relocating a derived object of the original base object");

llvm/test/Transforms/CodeGenPrepare/statepoint-relocate.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,28 @@ right:
122122
ret i32 %ret-base
123123
}
124124

125+
define i32 @test_sor_noop_same_bb(i1 %external-cond, i32* %base) gc "statepoint-example" {
126+
; CHECK-LABEL: @test_sor_noop_same_bb
127+
; Here base relocate doesn't dominate derived relocate. Make sure that we don't
128+
; produce undefined use of the relocated base pointer.
129+
entry:
130+
%ptr1 = getelementptr i32, i32* %base, i32 15
131+
; CHECK: getelementptr i32, i32* %base, i32 15
132+
%ptr2 = getelementptr i32, i32* %base, i32 5
133+
; CHECK: getelementptr i32, i32* %base, i32 5
134+
%tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, i32* %base, i32* %ptr1, i32* %ptr2)
135+
; CHECK: call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
136+
%ptr2-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 9)
137+
%ret2-new = load i32, i32* %ptr2-new
138+
; CHECK: getelementptr i32, i32* %base-new, i32 5
139+
%ptr1-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 8)
140+
%ret1-new = load i32, i32* %ptr1-new
141+
; CHECK: getelementptr i32, i32* %base-new, i32 15
142+
%base-new = call i32* @llvm.experimental.gc.relocate.p0i32(token %tok, i32 7, i32 7)
143+
%ret-new = add i32 %ret2-new, %ret1-new
144+
ret i32 %ret-new
145+
}
146+
125147
declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
126148
declare i32* @llvm.experimental.gc.relocate.p0i32(token, i32, i32)
127149
declare [3 x i32]* @llvm.experimental.gc.relocate.p0a3i32(token, i32, i32)

0 commit comments

Comments
 (0)