Skip to content

Commit cb1a9f7

Browse files
authored
[InstSimplify] Add trivial simplifications for gc.relocate intrinsic (#81639)
Fold gc.relocate of undef and null to undef and null respectively. Similar transform is currently done by instcombine, but there is no reason to not include it here as well.
1 parent 0de2b26 commit cb1a9f7

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "llvm/IR/Instructions.h"
4040
#include "llvm/IR/Operator.h"
4141
#include "llvm/IR/PatternMatch.h"
42+
#include "llvm/IR/Statepoint.h"
4243
#include "llvm/Support/KnownBits.h"
4344
#include <algorithm>
4445
#include <optional>
@@ -6847,6 +6848,27 @@ static Value *simplifyIntrinsic(CallBase *Call, Value *Callee,
68476848
}
68486849
case Intrinsic::experimental_constrained_ldexp:
68496850
return simplifyLdexp(Args[0], Args[1], Q, true);
6851+
case Intrinsic::experimental_gc_relocate: {
6852+
GCRelocateInst &GCR = *cast<GCRelocateInst>(Call);
6853+
Value *DerivedPtr = GCR.getDerivedPtr();
6854+
Value *BasePtr = GCR.getBasePtr();
6855+
6856+
// Undef is undef, even after relocation.
6857+
if (isa<UndefValue>(DerivedPtr) || isa<UndefValue>(BasePtr)) {
6858+
return UndefValue::get(GCR.getType());
6859+
}
6860+
6861+
if (auto *PT = dyn_cast<PointerType>(GCR.getType())) {
6862+
// For now, the assumption is that the relocation of null will be null
6863+
// for most any collector. If this ever changes, a corresponding hook
6864+
// should be added to GCStrategy and this code should check it first.
6865+
if (isa<ConstantPointerNull>(DerivedPtr)) {
6866+
// Use null-pointer of gc_relocate's type to replace it.
6867+
return ConstantPointerNull::get(PT);
6868+
}
6869+
}
6870+
return nullptr;
6871+
}
68506872
default:
68516873
return nullptr;
68526874
}

llvm/test/Transforms/InstSimplify/gc_relocate.ll

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,34 @@ define void @dead_relocate(ptr addrspace(1) %in) gc "statepoint-example" {
1111
;
1212
entry:
1313
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %in)]
14-
%a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
14+
%a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
1515
ret void
1616
}
1717

18+
define ptr addrspace(1) @relocate_undef() gc "statepoint-example" {
19+
; CHECK-LABEL: @relocate_undef(
20+
; CHECK-NEXT: entry:
21+
; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) undef) ]
22+
; CHECK-NEXT: ret ptr addrspace(1) undef
23+
;
24+
entry:
25+
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) undef)]
26+
%a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
27+
ret ptr addrspace(1) %a
28+
}
29+
30+
define ptr addrspace(1) @relocate_null() gc "statepoint-example" {
31+
; CHECK-LABEL: @relocate_null(
32+
; CHECK-NEXT: entry:
33+
; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) null) ]
34+
; CHECK-NEXT: ret ptr addrspace(1) null
35+
;
36+
entry:
37+
%safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) null)]
38+
%a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
39+
ret ptr addrspace(1) %a
40+
}
41+
42+
1843
declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)
1944
declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)

0 commit comments

Comments
 (0)