Skip to content

Commit 61d22f2

Browse files
author
Serguei Katkov
committed
[Greedy RA] Add a check to MachineVerifier
If Virtual Register is alive in landing pad its def must be before the call causing the exception or it should be statepoint instruction itself and in this case def actually means the relocation of gc pointer and is alive in landing pad. The test shows the triggering this check for an option under development use-registers-for-gc-values-in-landing-pad which is off by default until it is functionally correct. Reviewers: reames, void, jyknight, nickdesaulniers, efriedma, arsenm, rnk Reviewed By: rnk Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D100525
1 parent 35e95c6 commit 61d22f2

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,6 +2972,15 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
29722972
// Check that VNI is live-out of all predecessors.
29732973
for (const MachineBasicBlock *Pred : MFI->predecessors()) {
29742974
SlotIndex PEnd = LiveInts->getMBBEndIdx(Pred);
2975+
// Predecessor of landing pad live-out on last call.
2976+
if (MFI->isEHPad()) {
2977+
for (auto I = Pred->rbegin(), E = Pred->rend(); I != E; ++I) {
2978+
if (I->isCall()) {
2979+
PEnd = Indexes->getInstructionIndex(*I).getBoundaryIndex();
2980+
break;
2981+
}
2982+
}
2983+
}
29752984
const VNInfo *PVNI = LR.getVNInfoBefore(PEnd);
29762985

29772986
// All predecessors must have a live-out value. However for a phi
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
; REQUIRES: asserts
2+
; RUN: not --crash llc -o /dev/null %s -max-registers-for-gc-values=15 -use-registers-for-gc-values-in-landing-pad=true -verify-regalloc 2>&1 | FileCheck %s
3+
4+
; The test checks the verification catch the case when RA splits live interval in the
5+
; way the def is located after invoke statepoint while use is in landing pad.
6+
7+
; CHECK: *** Bad machine code: Register not marked live out of predecessor ***
8+
9+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
10+
target triple = "x86_64-unknown-linux-gnu"
11+
12+
define void @wombat(i8 addrspace(1)* %arg, i32 %arg1, i32 addrspace(1)* %arg2) gc "statepoint-example" personality i32* ()* @widget {
13+
bb:
14+
%tmp = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* null, align 8
15+
%tmp3 = load i32, i32 addrspace(1)* null, align 4
16+
%tmp4 = getelementptr inbounds i32, i32 addrspace(1)* %arg2, i64 24
17+
%tmp5 = load i32, i32 addrspace(1)* %tmp4, align 4
18+
%tmp6 = getelementptr inbounds i32, i32 addrspace(1)* %arg2, i64 40
19+
%tmp7 = load i32, i32 addrspace(1)* %tmp6, align 4
20+
%tmp8 = load i32, i32 addrspace(1)* null, align 4
21+
%tmp9 = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* undef, align 8
22+
%tmp10 = getelementptr inbounds i32, i32 addrspace(1)* %arg2, i64 88
23+
%tmp11 = load i32, i32 addrspace(1)* %tmp10, align 4
24+
%tmp12 = getelementptr inbounds i8, i8 addrspace(1)* %arg, i64 96
25+
%tmp13 = bitcast i8 addrspace(1)* %tmp12 to i8 addrspace(1)* addrspace(1)*
26+
%tmp14 = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* %tmp13, align 8
27+
%tmp15 = getelementptr inbounds i8, i8 addrspace(1)* %arg, i64 104
28+
%tmp16 = bitcast i8 addrspace(1)* %tmp15 to i8 addrspace(1)* addrspace(1)*
29+
%tmp17 = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* %tmp16, align 8
30+
%tmp18 = add i32 %tmp3, -1
31+
%tmp19 = load atomic i64, i64 addrspace(1)* undef unordered, align 8
32+
%tmp20 = invoke token (i64, i32, i32 (i32, i8 addrspace(1)*, i32, i32, i32)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32i32p1i8i32i32i32f(i64 1, i32 16, i32 (i32, i8 addrspace(1)*, i32, i32, i32)* nonnull @wombat.1, i32 5, i32 0, i32 0, i8 addrspace(1)* null, i32 undef, i32 %arg1, i32 0, i32 0, i32 0) [ "deopt"(i32 %tmp18, i8 addrspace(1)* %tmp, i32 %arg1, i32 %tmp3, i32 %tmp5, i32 %tmp7, i32 %tmp8, i8 addrspace(1)* %tmp9, i32 %tmp11, i8 addrspace(1)* %tmp14, i8 addrspace(1)* %tmp17), "gc-live"(i8 addrspace(1)* %tmp, i8 addrspace(1)* %tmp9, i8 addrspace(1)* %tmp14, i8 addrspace(1)* %tmp17) ]
33+
to label %bb21 unwind label %bb26
34+
35+
bb21: ; preds = %bb
36+
%tmp22 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %tmp20, i32 0, i32 0) ; (%tmp, %tmp)
37+
%tmp23 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %tmp20, i32 2, i32 2) ; (%tmp14, %tmp14)
38+
%tmp24 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %tmp20, i32 3, i32 3) ; (%tmp17, %tmp17)
39+
%tmp25 = call token (i64, i32, void (i32)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32f(i64 2882400000, i32 0, void (i32)* nonnull @quux, i32 1, i32 2, i32 10, i32 0, i32 0) [ "deopt"(i32 %tmp18, i8 addrspace(1)* %tmp22, i32 %arg1, i32 %tmp3, i32 %tmp5, i32 %tmp7, i32 %tmp8, i32 %tmp11, i8 addrspace(1)* %tmp23, i8 addrspace(1)* %tmp24), "gc-live"() ]
40+
ret void
41+
42+
bb26: ; preds = %bb
43+
%tmp27 = landingpad token
44+
cleanup
45+
%tmp28 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %tmp27, i32 1, i32 1) ; (%tmp9, %tmp9)
46+
%tmp29 = call token (i64, i32, void (i32)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32f(i64 2882400000, i32 0, void (i32)* nonnull @quux, i32 1, i32 0, i32 -271, i32 0, i32 0) [ "deopt"(i32 %arg1, i32 %tmp3, i32 %tmp5, i32 %tmp8, i8 addrspace(1)* %tmp28, i32 %tmp11), "gc-live"() ]
47+
unreachable
48+
}
49+
50+
declare i32* @widget()
51+
52+
declare i32 @wombat.1(i32, i8 addrspace(1)*, i32, i32, i32)
53+
54+
declare void @quux(i32)
55+
56+
declare token @llvm.experimental.gc.statepoint.p0f_isVoidi32f(i64 immarg, i32 immarg, void (i32)*, i32 immarg, i32 immarg, ...)
57+
58+
; Function Attrs: nounwind readonly
59+
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32 immarg, i32 immarg) #0
60+
61+
declare token @llvm.experimental.gc.statepoint.p0f_i32i32p1i8i32i32i32f(i64 immarg, i32 immarg, i32 (i32, i8 addrspace(1)*, i32, i32, i32)*, i32 immarg, i32 immarg, ...)
62+
63+
attributes #0 = { nounwind readonly }

0 commit comments

Comments
 (0)