Skip to content

Commit 21560fe

Browse files
authoredFeb 4, 2025
GlobalISel: Fix defined register of invariant.start (llvm#125664)
In contrast to SelectionDAG, GlobalISel created a new virtual register for the return value of invariant.start, leaving subsequent users of the invariant.start value with an undefined reference. A minimal example: ``` %tmp = alloca i32, align 4, addrspace(5) %tmpI = call ptr @llvm.invariant.start.p5(i64 4, ptr addrspace(5) %tmp) #3 call void @llvm.invariant.end.p5(ptr %tmpI, i64 4, ptr addrspace(5) %tmp) #3 store i32 %i, ptr %tmpI, align 4 ``` Although the return value of invariant.start might not be intended for any use beyond invariant.end (the fuzzer might not have created a sensible situation here), an implicit definition of the corresponding virtual register avoids a segfault in the target instruction selector later. This LLVM defect was identified via the AMD Fuzzing project.
1 parent 906eeed commit 21560fe

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed
 

‎llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -2441,9 +2441,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
24412441
return true;
24422442
}
24432443
case Intrinsic::invariant_start: {
2444-
LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
2445-
Register Undef = MRI->createGenericVirtualRegister(PtrTy);
2446-
MIRBuilder.buildUndef(Undef);
2444+
MIRBuilder.buildUndef(getOrCreateVReg(CI));
24472445
return true;
24482446
}
24492447
case Intrinsic::invariant_end:

‎llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -2262,7 +2262,7 @@ declare ptr @llvm.invariant.start.p0(i64, ptr nocapture) readonly nounwind
22622262
declare void @llvm.invariant.end.p0(ptr, i64, ptr nocapture) nounwind
22632263
define void @test_invariant_intrin() {
22642264
; CHECK-LABEL: name: test_invariant_intrin
2265-
; CHECK: %{{[0-9]+}}:_(s64) = G_IMPLICIT_DEF
2265+
; CHECK: %{{[0-9]+}}:_(p0) = G_IMPLICIT_DEF
22662266
; CHECK-NEXT: RET_ReallyLR
22672267
%x = alloca %t
22682268
%inv = call ptr @llvm.invariant.start.p0(i64 8, ptr %x)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -O0 -global-isel=true --stop-after=irtranslator -o - %s | FileCheck %s
3+
4+
declare ptr @llvm.invariant.start.p5(i64 immarg, ptr addrspace(5) nocapture)
5+
declare void @llvm.invariant.end.p5(ptr, i64 immarg, ptr addrspace(5) nocapture)
6+
7+
define void @use_invariant_promotable_lds(ptr addrspace(5) %arg, i32 %i) {
8+
; CHECK-LABEL: name: use_invariant_promotable_lds
9+
; CHECK: bb.1.bb:
10+
; CHECK-NEXT: liveins: $vgpr0, $vgpr1
11+
; CHECK-NEXT: {{ $}}
12+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p5) = COPY $vgpr0
13+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1
14+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
15+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
16+
; CHECK-NEXT: G_STORE [[C]](s32), [[DEF]](p0) :: (store (s32) into %ir.tmp)
17+
; CHECK-NEXT: SI_RETURN
18+
bb:
19+
%tmp = call ptr @llvm.invariant.start.p5(i64 4, ptr addrspace(5) %arg)
20+
call void @llvm.invariant.end.p5(ptr %tmp, i64 4, ptr addrspace(5) %arg)
21+
store i32 0, ptr %tmp, align 4
22+
ret void
23+
}

0 commit comments

Comments
 (0)