mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-16 00:17:32 +00:00
AMDGPU: Whitelist handled intrinsics
We shouldn't crash on unhandled intrinsics. Also simplify failure handling in loop. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259546 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
374613d697
commit
53b80ebb13
@ -399,15 +399,37 @@ static bool tryPromoteAllocaToVector(AllocaInst *Alloca) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isCallPromotable(CallInst *CI) {
|
||||
// TODO: We might be able to handle some cases where the callee is a
|
||||
// constantexpr bitcast of a function.
|
||||
if (!CI->getCalledFunction())
|
||||
return false;
|
||||
|
||||
IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
|
||||
if (!II)
|
||||
return false;
|
||||
|
||||
switch (II->getIntrinsicID()) {
|
||||
case Intrinsic::memcpy:
|
||||
case Intrinsic::memset:
|
||||
case Intrinsic::lifetime_start:
|
||||
case Intrinsic::lifetime_end:
|
||||
case Intrinsic::invariant_start:
|
||||
case Intrinsic::invariant_end:
|
||||
case Intrinsic::invariant_group_barrier:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) {
|
||||
bool Success = true;
|
||||
for (User *User : Val->users()) {
|
||||
if(std::find(WorkList.begin(), WorkList.end(), User) != WorkList.end())
|
||||
if (std::find(WorkList.begin(), WorkList.end(), User) != WorkList.end())
|
||||
continue;
|
||||
|
||||
if (CallInst *CI = dyn_cast<CallInst>(User)) {
|
||||
// TODO: We might be able to handle some cases where the callee is a
|
||||
// constantexpr bitcast of a function.
|
||||
if (!CI->getCalledFunction())
|
||||
if (!isCallPromotable(CI))
|
||||
return false;
|
||||
|
||||
WorkList.push_back(User);
|
||||
@ -429,10 +451,11 @@ static bool collectUsesWithPtrTypes(Value *Val, std::vector<Value*> &WorkList) {
|
||||
continue;
|
||||
|
||||
WorkList.push_back(User);
|
||||
|
||||
Success &= collectUsesWithPtrTypes(User, WorkList);
|
||||
if (!collectUsesWithPtrTypes(User, WorkList))
|
||||
return false;
|
||||
}
|
||||
return Success;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) {
|
||||
@ -521,6 +544,11 @@ void AMDGPUPromoteAlloca::visitAlloca(AllocaInst &I) {
|
||||
|
||||
IntrinsicInst *Intr = dyn_cast<IntrinsicInst>(Call);
|
||||
if (!Intr) {
|
||||
// FIXME: What is this for? It doesn't make sense to promote arbitrary
|
||||
// function calls. If the call is to a defined function that can also be
|
||||
// promoted, we should be able to do this once that function is also
|
||||
// rewritten.
|
||||
|
||||
std::vector<Type*> ArgTypes;
|
||||
for (unsigned ArgIdx = 0, ArgEnd = Call->getNumArgOperands();
|
||||
ArgIdx != ArgEnd; ++ArgIdx) {
|
||||
|
24
test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll
Normal file
24
test/CodeGen/AMDGPU/promote-alloca-unhandled-intrinsic.ll
Normal file
@ -0,0 +1,24 @@
|
||||
; RUN: opt -S -mtriple=amdgcn-unknown-amdhsa < %s | FileCheck %s
|
||||
|
||||
; This is just an arbitrary intrinisic that shouldn't ever need to be
|
||||
; handled to ensure it doesn't crash.
|
||||
|
||||
declare void @eh.sjlj.functioncontext(i8*) #2
|
||||
|
||||
; CHECK-LABEL: @try_promote_unhandled_intrinsic(
|
||||
; CHECK: alloca
|
||||
; CHECK: call void @eh.sjlj.functioncontext(i8* %tmp1)
|
||||
define void @try_promote_unhandled_intrinsic(i32 addrspace(1)* %arg) #2 {
|
||||
bb:
|
||||
%tmp = alloca i32, align 4
|
||||
%tmp1 = bitcast i32* %tmp to i8*
|
||||
%tmp2 = getelementptr inbounds i32, i32 addrspace(1)* %arg, i64 1
|
||||
%tmp3 = load i32, i32 addrspace(1)* %tmp2
|
||||
store i32 %tmp3, i32* %tmp
|
||||
call void @eh.sjlj.functioncontext(i8* %tmp1)
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { argmemonly nounwind }
|
||||
attributes #1 = { nounwind readnone }
|
||||
attributes #2 = { nounwind }
|
Loading…
Reference in New Issue
Block a user